﻿/*
 * Rappelz: Endless Odyssey - The first free open source Rappelz server emulator
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Rappelz.GameServer.Network;
using Rappelz.GameServer.Network.GameClient;
using Rappelz.GameServer.Network.AuthClient;
using Rappelz.GameServer.Scripting;

namespace Rappelz.GameServer
{
    class Messages
    {
        public class scramble_map
        {
            public scramble_map()
            {
                int v3;
                int i;
                byte v5;

                for (i = 0; i < 32; ++i)
                {
                    map[i] = (byte)i;
                }

                v3 = 3;
                for (i = 0; i < 32; ++i)
                {
                    v5 = map[i];
                    if (v3 >= 32)
                        v3 += -32 * (v3 >> 5);
                    map[i] = map[v3];
                    map[v3] = v5;
                    v3 += i + 3;
                }
            }
            public byte[] map = new byte[32];
        }

        private static scramble_map map = new scramble_map();

        private static int bits_scramble(int c)
        {
            int result;
            uint v2;

            result = 0;
            v2 = 0;
            do
            {
                if ((((uint)1 << (int)v2) & c) != 0)
                    result |= 1 << map.map[v2];
                ++v2;
            }
            while (v2 < 32);
            return result;
        }

        public static void BroadcastAttackTeamInfo(int nPartyID)
        {
//             int v1; // ebp@0
//             int v2; // ST14_4@1
//             PartyManager *v3; // eax@1
//             const char *v4; // eax@2
// 
//             v2 = *(v1 + 8);
//             v3 = PartyManager::GetInstance();
//             PartyManager::GetRaidPartyInfo(v3, (v1 - 44), v2);
//             *(v1 - 4) = 0;
//             if ( *(v1 - 24) )
//             {
//                 v4 = *(v1 - 40);
//                 if ( *(v1 - 20) < 0x10u )
//                     v4 = (v1 - 40);
//                 SendAttackTeamChatMessage(0, 130, "@RAID", *(v1 + 8), v4);
//             }
//             std::basic_string<char_std::char_traits<char>_std::allocator<char>>::_Tidy((v1 - 44), 1, 0);
        }

        public static void BroadcastGuildMemberInfo(int nGuildID, Player pPlayer)
        {
//             StructPlayer *v2; // esi@1
//             int v3; // ST34_4@1
//             int v4; // ST30_4@1
//             unsigned int v5; // eax@1
//             char buf[256]; // [sp+Ch] [bp-78h]@1
//             unsigned int v7; // [sp+10Ch] [bp+88h]@1
// 
//             v7 = &buf[120] ^ __security_cookie;
//             v2 = pPlayer;
//             v3 = StructCreature::GetMPPercentage(&pPlayer->baseclass_0);
//             v4 = StructCreature::GetHPPercentage(&pPlayer->baseclass_0);
//             v2->baseclass_0.baseclass_0.baseclass_0.baseclass_0.vfptr[4].IsDeleteable(v2);
//             v2->baseclass_0.baseclass_0.baseclass_0.baseclass_0.vfptr[3].IsDeleteable(v2);
//             v2->baseclass_0.baseclass_0.baseclass_0.baseclass_0.vfptr[3].GetHandle(v2);
//             v2->baseclass_0.baseclass_0.baseclass_0.baseclass_0.vfptr->GetHandle(v2);
//             sprintf(buf, "MINFO|%d|%s|%d|%d|%d|%d|%d|%d|%d|");
//             strlen(buf);
//             SendGuildChatMessage(110, "@GUILD", nGuildID, buf, v5);
        }

        public static void BroadcastHPMPMsg(Creature creature, int add_hp, float add_mp, bool need_to_display)
        {
            PacketOut o = new PacketOut(509);
            o.WriteUInt32(creature.m_hHandle);
            o.WriteInt32(add_hp);
            o.WriteInt32(creature.m_nHP);
            o.WriteInt32(creature.m_nMaxHP);
            o.WriteInt32((int)add_mp);
            o.WriteInt32((int)creature.m_fMP);
            o.WriteInt32(creature.m_nMaxMP);
            o.WriteByte((byte)(need_to_display ? 1 : 0));
            RappelzServer.Instance.Broadcast((uint)(creature.mv.x / GameContent.g_nRegionSize), (uint)(creature.mv.y / GameContent.g_nRegionSize), creature.m_layer, o);
        }

        public static void BroadcastLevelMsg(Creature creature)
        {
            PacketOut o = new PacketOut((ushort)ClientOutPackets.LevelMessage);
            o.WriteUInt32(creature.m_hHandle);
            o.WriteInt32(creature.GetLevel());
            o.WriteInt32(creature.GetJobLevel());
            RappelzServer.Instance.Broadcast((uint)(creature.mv.x / GameContent.g_nRegionSize), (uint)(creature.mv.y / GameContent.g_nRegionSize), creature.m_layer, o);

        }

        public static void BroadcastPartyDestroy(int nPartyID)
        {
//             PartyManager *v1; // eax@1
//             PartyManager *v2; // eax@2
//             PartyManager *v3; // eax@3
//             PartyManager *v4; // eax@4
//             BroadcastPartyDestroy::__l2::myPartyDestroyFunctor _fo; // [sp+4h] [bp-4h]@1
// 
//             v1 = PartyManager::GetInstance();
//             _fo.baseclass_0.vfptr = (PartyManager::PartyFunctorVtbl *)&::::myPartyDestroyFunctor::_vftable_;
//             if ( PartyManager::IsAttackTeamParty(v1, nPartyID)
//               && (v2 = PartyManager::GetInstance(), nPartyID == PartyManager::GetAttackTeamLeadPartyID(v2, nPartyID)) )
//             {
//                 v3 = PartyManager::GetInstance();
//                 PartyManager::DoEachAttackTeamMember(v3, nPartyID, &_fo.baseclass_0);
//             }
//             else
//             {
//                 v4 = PartyManager::GetInstance();
//                 PartyManager::DoEachMember(v4, nPartyID, &_fo.baseclass_0);
//             }
        }

        public static void BroadcastPartyMemberInfo(int nPartyID, Player pPlayer)
        {
//             StructPlayer *v2; // esi@1
//             int v3; // ST34_4@1
//             int v4; // ST30_4@1
//             unsigned int v5; // eax@1
//             char buf[256]; // [sp+Ch] [bp-78h]@1
//             unsigned int v7; // [sp+10Ch] [bp+88h]@1
// 
//             v7 = &buf[120] ^ __security_cookie;
//             v2 = pPlayer;
//             v3 = StructCreature::GetMPPercentage(&pPlayer->baseclass_0);
//             v4 = StructCreature::GetHPPercentage(&pPlayer->baseclass_0);
//             v2->baseclass_0.baseclass_0.baseclass_0.baseclass_0.vfptr[4].IsDeleteable(v2);
//             v2->baseclass_0.baseclass_0.baseclass_0.baseclass_0.vfptr[3].IsDeleteable(v2);
//             v2->baseclass_0.baseclass_0.baseclass_0.baseclass_0.vfptr[3].GetHandle(v2);
//             v2->baseclass_0.baseclass_0.baseclass_0.baseclass_0.vfptr->GetHandle(v2);
//             sprintf(buf, "MINFO|%d|%s|%d|%d|%d|%d|%d|%d|%d|");
//             strlen(buf);
//             SendPartyChatMessage(100, "@PARTY", nPartyID, buf, v5);
        }

        public static void BroadcastPropertyMessage(uint rx, uint ry, sbyte layer, uint handle, string szPropertyName, long value)
        {
//             ArcadiaServer *v6; // eax@1
//             TS_SC_PROPERTY msg; // [sp+8h] [bp-28h]@1
//             unsigned int v8; // [sp+2Ch] [bp-4h]@1
//             int v9; // [sp+30h] [bp+0h]@1
// 
//             v8 = &v9 ^ __security_cookie;
//             TS_SC_PROPERTY::TS_SC_PROPERTY(&msg);
//             strncpy(msg.name, szPropertyName, 0x10u);
//             msg.handle = handle;
//             msg.value = *value;
//             msg.is_number = 1;
//             v6 = ArcadiaServer::Instance();
            //             RappelzServer.Instance.Broadcast(rx, ry, layer, &msg);
        }

        public static void BroadcastStateMessage(Creature pCreature, State pState, bool bIsCancel)
        {
//             unsigned __int16 v3; // ax@2
//             bool v4; // zf@2
//             unsigned int v5; // ecx@4
//             unsigned int v6; // esi@6
//             FileLogHandler *v7; // eax@11
//             XConsole *v8; // eax@11
//             float v9; // ST20_4@13
//             char v10; // ST08_1@13
//             unsigned int v11; // ST04_4@13
//             unsigned int v12; // ST00_4@13
//             ArcadiaServer *v13; // eax@13
//             TS_SC_STATE msg; // [sp+14h] [bp-44h]@1
//             unsigned int v15; // [sp+54h] [bp-4h]@1
//             int v16; // [sp+58h] [bp+0h]@1
// 
            PacketOut pak = new PacketOut(ClientOutPackets.State);
            pak.WriteUInt32(pCreature.m_hHandle);
            pak.WriteUInt16(pState.m_nUID);
            pak.WriteInt32((int)pState.m_nCode);


            if ( bIsCancel )
            {
                pak.WriteUInt16(0);
                pak.WriteUInt32(0);
                pak.WriteUInt32(0);
            }
            else
            {
                pak.WriteUInt16(pState.GetLevel());
                uint t; 

                if (!pState.m_bAura)
                {
                    t = pState.m_nEndTime[0];
                    if (t <= pState.m_nEndTime[1])
                        t = pState.m_nEndTime[1];
                    pak.WriteUInt32(t);
                }
                else
                {
                    pak.WriteInt32(-1);
                }

                t = pState.m_nStartTime[1];
                if (pState.m_nStartTime[0] > t)
                    t = pState.m_nStartTime[0];
                pak.WriteUInt32(t);

            }
            pak.WriteInt32(pState.m_nStateValue);
            pak.FillString(pState.m_szStateValue, 32);

            RappelzServer.Instance.Broadcast((uint)(pCreature.mv.x / GameContent.g_nRegionSize), (uint)(pCreature.mv.y / GameContent.g_nRegionSize), pCreature.m_layer, pak);
        }

        public static void BroadcastStatusMessage(Creature creature)
        {
            BroadcastStatusMessageArObjectFunctor _sender = new BroadcastStatusMessageArObjectFunctor();
            BroadcastStatusMessageArRegionFunctor _fo = new BroadcastStatusMessageArRegionFunctor();

            _sender.pIntf = RappelzServer.m_Intf;
            _sender.pCreature = creature;
            _fo.pFo = _sender;

            RappelzServer.Instance.DoEachVisibleRegion((int)((float)creature.mv.x / GameContent.g_nRegionSize),
                (int)((float)creature.mv.y / GameContent.g_nRegionSize), creature.m_layer, _fo);
        }

        public static void BroadcastTamingMessage(Player pPlayer, Creature pMonster, int mode)
        {
            if (pPlayer == null || pPlayer.Connection == null)
                return;

            PacketOut pak = new PacketOut((ushort)ClientOutPackets.TamingInfo);

// Enum           :   <unnamed-tag>, Type: int
// Data           :     constant 0x0, Constant, Type: int, START
// Data           :     constant 0x1, Constant, Type: int, CLEAR
// Data           :     constant 0x2, Constant, Type: int, SUCCESS
// Data           :     constant 0x3, Constant, Type: int, FAILED
// Data           :   this+0x7, Member, Type: unsigned char, mode
// Data           :   this+0x8, Member, Type: unsigned int, tamer_handle
// Data           :   this+0xC, Member, Type: unsigned int, target_handle


            
            pak.WriteByte((byte)mode);
            pak.WriteUInt32(pPlayer.m_hHandle);
            pak.WriteUInt32(pMonster.m_hHandle);

            string strRes;

            RappelzServer.Instance.Broadcast((uint)(pMonster.mv.x / GameContent.g_nRegionSize), (uint)(pMonster.mv.y / GameContent.g_nRegionSize), pMonster.m_layer, pak);
            switch(mode)
            {
                case 0:
                    strRes = String.Format("TAMING_START|{0}|", pMonster.GetName());
                    break;

                case 1:
                case 3:
                    strRes = String.Format("TAMING_FAILED|{0}|", pMonster.GetName());
                    break;

                case 2:
                    strRes = String.Format("TAMING_SUCCESS|{0}|", pMonster.GetName());
                    break;

                default:
                    return;

            }

            if (pPlayer.m_nPartyId != 0)
                PrintfPartyChatMessage(100, pPlayer.m_nPartyId, strRes);
            else
                PrintfChatMessage(false, 100, "@SYSTEM", pPlayer, strRes);
        }

        public static void fillItemInfo(PacketOut packet, Item item)
        {
            ItemInfoSC data = new ItemInfoSC();
            fillItemBaseInfo(data, item);
            data.wear_position = (short)item.m_Instance.nWearInfo;
            data.own_summon_handle = 0;

            if (item.m_Instance.nOwnSummonUID > 0)
                data.own_summon_handle = item.m_Instance.OwnSummonHandle;
            if (item.IsInStorage())
                data.wear_position = -2;
            data.index = item.m_Instance.nIdx;
            data.WriteToPacket(packet);
        }

        public static void fillItemBaseInfo(ItemInfoBaseSC info, Item item)
        {
            info.Code = item.m_Instance.Code;
            info.count = item.m_Instance.nCount;
            info.flag = item.m_Instance.Flag;
            info.handle = item.m_hHandle;
            info.endurance = (uint)item.m_Instance.nCurrentEndurance;
            info.dura = item.m_Instance.nDurability;
            info.enhance = (byte)item.m_Instance.nEnhance;
            info.level = (byte)item.m_Instance.nLevel;
            info.uid = item.m_Instance.UID;

            long ct = Globals.Time64();
            if (item.IsExpireItem())
                info.remain_time = (int)(item.m_Instance.tExpire - ct);
            else
                info.remain_time = 0;

            for (int i = 0; i < 4; ++i)
            {
                info.socket[i] = item.m_Instance.Socket[i];
            }

            if (item.m_Instance.tElementalEffectExpire <= ct)
            {
                info.elemental_effect_type = 0;
                info.elemental_effect_remain_time = 0;
                info.elemental_effect_attack_point = 0;
                info.elemental_effect_magic_point = 0;
            }
            else
            {
                info.elemental_effect_type = (byte)item.GetElementalEffectType();
                info.elemental_effect_remain_time = (int)(item.m_Instance.tElementalEffectExpire - ct);
                info.elemental_effect_attack_point = item.m_Instance.nElementalEffectAttackPoint;
                info.elemental_effect_magic_point = item.m_Instance.nElementalEffectMagicPoint;
            }

            if (item.m_pItemBase.nGroup == 13)
            {
                if (item.m_pSummon != null)
                {
                    int slot = 1;
                    int tl = item.m_pSummon.GetTransformLevel();
                    while (slot < tl)
                    {
                        info.socket[slot] = item.m_pSummon.GetPrevJobLevel(slot - 1);
                        ++slot;
                    }
                    info.socket[slot] = item.m_pSummon.GetLevel();
                }
            }
        }


        public static uint GetStatusCode(Creature pCreature, Player pClient)
        {
            uint v2; // ebx@1
            //             bool v3; // zf@5
            //             ArSchedulerObjectVtbl *v4; // eax@5
            //             int v5; // eax@8
            //             float v6; // esi@26
            //             CompeteManager *v7; // eax@27

            v2 = 0;
/*
            if (pCreature.GetHandle() != 0)
                v2 = 1;
            if ((pCreature.m_StatusFlag & Creature.StatusFlags.Invisible) != 0)
                v2 |= 2;
*/

            if (!pCreature.IsPlayer())
            {
                if (pCreature.IsNPC())
                {
                    NPC npc = (NPC)pCreature;
                    if (npc.HasFinishableQuest(pClient))
                    {
                        v2 |= 0x400;
                    }
                    else if (npc.HasStartableQuest(pClient))
                    {
                        v2 |= 0x100;
                    }
                    else if (npc.HasInProgressQuest(pClient))
                    {
                        v2 |= 0x200;
                    }
                }
                else
                {
                    if (pCreature.IsMonster())
                    {
                        Monster mob = (Monster)pCreature;
                        if (mob.m_bIsDungeonOwnerGuardian)
                            v2 |= 0x8000;
                        if (mob.m_bIsDungeonSiegerGuardian)
                            v2 |= 0x20000;
                        if (mob.m_nStatus == 4)
                            v2 |= 0x100;
                    }
                    else
                    {
                        if (pCreature.IsPet() && pCreature.IsUsingSkill() && pCreature.m_pCastSkill.m_SkillBase.uid == 6907)
                        {
                            Pet pet = (Pet)pCreature;
                            switch (pet.m_nShovelingStatus)
                            {
                                case Pet.ShovelingStatus.Search:
                                    v2 |= 0x40000;
                                    break;
                                case Pet.ShovelingStatus.Approach:
                                    v2 |= 0x80000;
                                    break;
                                case Pet.ShovelingStatus.Dig:
                                    v2 |= 0x100000;
                                    break;
                            }
                        }
                    }
                }
            }
            else
            {
                Player player = pCreature as Player;

                if (player.IsSitDown())
                    v2 |= 0x100;

                if (player.m_BoothStatus == Player.BoothStatus.BuyBooth)
                    v2 |= 0x200;
                if (player.m_BoothStatus == Player.BoothStatus.SellBooth)
                    v2 |= 0x400;
                if (player.m_bIsPK)
                    v2 |= 0x800;
                if (player.m_fImmoralPoint > GameRule.fMoralLimit)
                    v2 |= 0x1000;
                if (player.m_fImmoralPoint > GameRule.fCrimeLimit)
                    v2 |= 0x2000;
                if (player.m_nPermission >= 100)
                    v2 |= 0x4000;
                if (player.IsDungeonOriginalOwner())
                    v2 |= 0x8000;
//                 if (player.IsDungeonOriginalSieger())
//                     v2 |= 0x20000u;
                if (player.m_bWalk)
                    v2 |= 0x10000;

                if (player.m_nCompeteID != 0)
                {
//                     v7 = CompeteManager::Instance();
//                     if ( CompeteManager::IsStarted(v7, v6, 1) )
//                         v2 |= 0x200000u;
                }
            }
            return v2;
        }

        public static void GetWearMsg(Creature creature, PacketOut packet)
        {
            uint handle;
            int[] itemCode = new int[ItemBase.MAX_ITEM_WEAR];
            int[] itemEnhance = new int[ItemBase.MAX_ITEM_WEAR];
            int[] itemLevel = new int[ItemBase.MAX_ITEM_WEAR];
            byte[] elemental_effect_type = new byte[ItemBase.MAX_ITEM_WEAR];
            int[] appearanceCode = new int[ItemBase.MAX_ITEM_WEAR];

            /*
             Data           :   this+0x7, Member, Type: unsigned int, handle
            Data           :   this+0xB, Member, Type: int[0x18], itemCode
            Data           :   this+0x6B, Member, Type: int[0x18], 
            Data           :   this+0xCB, Member, Type: int[0x18], 
            Data           :   this+0x12B, Member, Type: unsigned char[0x18], 
                        TS_WEAR_INFO *v2; // esi@1
                        char *v3; // ebx@1
                        int v4; // eax@2
                        signed int i; // [sp+18h] [bp+Ch]@1

                        v2 = itemInfoMsg;
                        memset((char *)itemInfoMsg->itemCode, 0, 0x60u);
                        v3 = (char *)itemInfoMsg->itemEnhance;
                        memset((char *)itemInfoMsg->itemEnhance, 0, 0x60u);
                        i = 0;
            */
            handle = creature.m_hHandle;

            for (int i = 0; i < ItemBase.MAX_ITEM_WEAR; ++i)
            {
                Item item = creature.GetWornItem((ItemBase.ItemWearType)i);
                if (item != null)
                {
                    itemCode[i] = item.m_Instance.Code;
                    itemEnhance[i] = item.m_Instance.nEnhance;
                    itemLevel[i] = item.m_Instance.nLevel;
                    elemental_effect_type[i] = (byte)item.GetElementalEffectType();
                    appearanceCode[i] = 0;
                }
            }
            if (creature.IsPlayer())
            {
                Player player = creature as Player;
                if (itemCode[2] == 0)
                    itemCode[2] = player.m_nBaseModelId[2];
                if (itemCode[4] == 0)
                    itemCode[4] = player.m_nBaseModelId[3];
                if (itemCode[5] == 0)
                    itemCode[5] = player.m_nBaseModelId[4];
            }

            // now write it out
            packet.WriteUInt32(handle);

            for (int i = 0; i < ItemBase.MAX_ITEM_WEAR; ++i)
            {
                packet.WriteInt32(itemCode[i]);
            }
            for (int i = 0; i < ItemBase.MAX_ITEM_WEAR; ++i)
            {
                packet.WriteInt32(itemEnhance[i]);
            }
            for (int i = 0; i < ItemBase.MAX_ITEM_WEAR; ++i)
            {
                packet.WriteInt32(itemLevel[i]);
            }
            for (int i = 0; i < ItemBase.MAX_ITEM_WEAR; ++i)
            {
                packet.WriteByte(elemental_effect_type[i]);
            }
            for (int i = 0; i < ItemBase.MAX_ITEM_WEAR; ++i)
            {
                packet.WriteInt32(appearanceCode[i]);
            }
        }


        public static void PrintfAllianceChatMessage(int nAllianceID, string szString, params object[] args)
        {
            string szBuf = String.Format(szString, args);
            PrintfAllianceChatMessage(nAllianceID, "@ALLIANCE", szBuf);
        }

        public static void PrintfAllianceChatMessage(int nAllianceID, string szSender, string szString, params object[] args)
        {
            string szBuf = String.Format(szString, args);
            PrintfAllianceChatMessage(150,nAllianceID, szSender, szBuf);
        }

        public static void PrintfAllianceChatMessage(int nChatType, int nAllianceID, string szSender, string szString, params object[] args)
        {
//             GuildManager *v4; // eax@1
//             ArMoveVector::MOVE_INFO *v5; // eax@2
//             std::vector<int,std::allocator<int> > vAllianceMember; // [sp+0h] [bp-2Ch]@1
//             std::_Vector_const_iterator<unsigned int,std::allocator<unsigned int> > this; // [sp+10h] [bp-1Ch]@3
//             std::_Vector_iterator<int,std::allocator<int> > it; // [sp+18h] [bp-14h]@1
//             int v9; // [sp+28h] [bp-4h]@1
//             char szBuf[2048]; // [sp+2Ch] [bp+0h]@1
//             unsigned int v11; // [sp+82Ch] [bp+800h]@1
//             int nChatTypea; // [sp+838h] [bp+80Ch]@2
//             int nAllianceIDa; // [sp+83Ch] [bp+810h]@1
//             const char *szSendera; // [sp+840h] [bp+814h]@2
//             const char *szStringa; // [sp+844h] [bp+818h]@1
//             char ap; // [sp+848h] [bp+81Ch]@1
// 
//             v11 = szBuf ^ __security_cookie;
//             _vsnprintf(szBuf, 0x800u, szStringa, &ap);
//             *&szBuf[2028] = nAllianceIDa;
//             *&szBuf[2024] = &vAllianceMember;
//             v4 = GuildManager::GetInstance();
//             GuildManager::GetAllianceMemberID(v4, *&szBuf[2024], *&szBuf[2028]);
//             v9 = 0;
//             std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
//                 &it,
//                 vAllianceMember._Myfirst,
//                 &vAllianceMember.baseclass_0.___u0.baseclass_0);
//             while ( 1 )
//             {
//                 std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
//                     &this,
//                     vAllianceMember._Mylast,
//                     &vAllianceMember.baseclass_0.___u0.baseclass_0);
//                 if ( std::_Vector_const_iterator<X2D::Point<float>_std::allocator<X2D::Point<float>>>::operator__(&it, &this) )
//                     break;
//                 v5 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
//                 *&szBuf[2028] = 0;
//                 *&szBuf[2024] = szBuf;
//                 *&szBuf[2020] = LODWORD(v5->end.x);
//                 SendGuildChatMessage(nChatTypea, szSendera, *&szBuf[2020], szBuf, 0);
//                 std::_Vector_const_iterator<AutoAuctionInfo___std::allocator<AutoAuctionInfo__>>::operator__(&it);
//             }
//             std::vector<GameContent::REGEN_INFO_std::allocator<GameContent::REGEN_INFO>>::_Tidy(&vAllianceMember);
        }

        public static void PrintfAttackTeamChatMessageByGuildID(bool bLock, int nChatType, string szSender, int nGuildID, string szString, params object[] args)
        {
            string szBuff = String.Format(szString, args);
            SendAttackTeamChatMessageByGuildID(bLock, nChatType, szSender, nGuildID, szBuff);
        }

        public static void PrintfChatMessage(bool bLock, int nChatType, string szSenderName, Player pTarget, string szString, params object[] args)
        {
            string szBuff = String.Format(szString, args);
            SendChatMessage(bLock, nChatType, szSenderName, pTarget, szBuff, 0);
        }

        public static void PrintfGlobalChatMessage(int nChatType, string szSenderName, string szString, params object[] args)
        {
            string szBuff = String.Format(szString, args);
            SendGlobalChatMessage(nChatType, szSenderName, szBuff, 0);
        }

        public static void PrintfGuildChatMessage(int nChatType, string szSender, int nGuildID, string szString, params object[] args)
        {
            string szBuff = String.Format(szString, args);
            SendGuildChatMessage(nChatType, szSender, nGuildID, szBuff, 0);
        }

        public static void PrintfGuildChatMessage(int nChatType, int nGuildID, string szString, params object[] args)
        {
            string szBuff = String.Format(szString, args);
            SendGuildChatMessage(nChatType, "@GUILD", nGuildID, szBuff, 0);
        }

        public static void PrintfPartyChatMessage(int nChatType, int nPartyID, string szString, params object[] args)
        {
            string szBuff = String.Format(szString, args);
            SendPartyChatMessage(nChatType, "@PARTY", nPartyID, szBuff, 0);
        }






        public static void SendAccountResultWithAuth(TCPConnection conn, string szAccount, int nError)
        {
            Messages.SendResult(conn, 2005, (ushort)nError, 0);
        }

        public static void SendAddPetMessage(Player player, Pet pet)
        {
            if (player == null || player.Connection == null)
                return;

            PacketOut pak = new PacketOut((ushort)ClientOutPackets.AddPetInfo);

            pak.WriteUInt32(pet.m_item.m_hHandle);
            pak.WriteUInt32(pet.m_hHandle);
            pak.FillString(pet.GetName(),19);
            pak.WriteInt32(pet.m_ContentInfo.uid);
            player.Connection.SendTCP(pak);
        }

        public static void SendAddSummonMessage(Player player, Summon summon)
        {
            if (player == null || player.Connection == null)
                return;

            PacketOut pak = new PacketOut((ushort)ClientOutPackets.AddSummon);

            pak.WriteUInt32(summon.m_item.m_hHandle);
            pak.WriteUInt32(summon.m_hHandle);
            pak.FillString(summon.GetName(),19);
            pak.WriteInt32(summon.GetSummonCode());
            pak.WriteInt32(summon.GetLevel());
            pak.WriteInt32(summon.m_nSP);

            player.Connection.SendTCP(pak);

            SendStatInfo(player, summon);
            SendHPMPMsg(player, summon, summon.m_nHP, summon.m_fMP, false);
            SendLevelMsg(player, summon);
            SendExpMsg(player, summon);
            SendSPMsg(player, summon);
        }

        public static void SendAttackTeamChatMessage(bool bLock, int nChatType, string szSender, int nPartyID, string szString)
        {
/*
            PartyManager *v5; // eax@1
            SendAttackTeamChatMessage::__l2::myAttackTeamFunctor _fo; // [sp+0h] [bp-10h]@1

            ::::myAttackTeamFunctor::myAttackTeamFunctor(&_fo, szSender, szString, nChatType);
            v5 = PartyManager::GetInstance();
            PartyManager::DoEachAttackTeamMember(v5, nPartyID, &_fo.baseclass_0);
*/
        }

        public static void SendAttackTeamChatMessageByGuildID(bool bLock, int nChatType, string szSender, int nGuildID, string szString)
        {
/*
            PartyManager *v5; // eax@1
            int v6; // eax@1

            v5 = PartyManager::GetInstance();
            v6 = PartyManager::GetAttackTeamLeadPartyIDByGuildID(v5, nGuildID);
            if ( v6 )
                SendAttackTeamChatMessage(bLock, nChatType, szSender, v6, szString);
*/
        }

        public static void SendAttackTeamInfo(Player pPlayer)
        {
/*
            int v1; // ebp@0
            int v2; // esi@1
            int v3; // edi@1
            int v4; // ST14_4@2
            PartyManager *v5; // eax@2
            PartyManager *v6; // eax@3
            const char *v7; // eax@3

            v2 = *(v1 + 8);
            v3 = *(v2 + 4244);
            if ( v3 )
            {
                v4 = *(v2 + 4244);
                v5 = PartyManager::GetInstance();
                if ( PartyManager::IsAttackTeamParty(v5, v4) )
                {
                    v6 = PartyManager::GetInstance();
                    PartyManager::GetRaidPartyInfo(v6, (v1 - 44), v3);
                    *(v1 - 4) = 0;
                    v7 = *(v1 - 40);
                    if ( *(v1 - 20) < 0x10u )
                        v7 = (v1 - 40);
                    SendChatMessage(0, 130, "@RAID", v2, v7, 0);
                    std::basic_string<char_std::char_traits<char>_std::allocator<char>>::_Tidy((v1 - 44), 1, 0);
                }
            }
*/
        }

        public static void SendBeltSlotInfo(Player player)
        {
            if (player == null || player.Connection == null)
                return;

            PacketOut pak = new PacketOut(ClientOutPackets.BeltSlotInfo);

            for(int i = 0; i < 6; ++i)
            {
                if(player.m_aBeltSlotCard[i] != null)
                    pak.WriteUInt32(player.m_aBeltSlotCard[i].m_hHandle);
                else
                    pak.WriteUInt32(0);
            }

            player.Connection.SendTCP(pak);
        }

        public static void SendBoothClosedMessage(Player pPlayer, uint target)
        {
//             TS_SC_BOOTH_CLOSED msg; // [sp+0h] [bp-Ch]@1
// 
//             TS_SC_BOOTH_CLOSED::TS_SC_BOOTH_CLOSED(&msg);
//             msg.target = target;
//             PendMessage(&pPlayer->baseclass_0.baseclass_0.baseclass_0, &msg.baseclass_0);
        }

        public static void SendBoothInfo(Player pPlayer, Player pTarget)
        {
/*
            int v2; // ebp@0
            int v3; // esi@1
            std::vector<ArPosition,std::allocator<ArPosition> > *v4; // eax@1
            std::vector<ArPosition,std::allocator<ArPosition> > *v5; // esi@1
            unsigned __int16 v6; // ax@1
            IQueue *v7; // edi@1
            IQueueVtbl *v8; // eax@1
            StructItem **v9; // eax@2
            __int64 v10; // qax@2
            ArMoveVector::MOVE_INFO *v11; // eax@2
            unsigned int v12; // ST50_4@4
            const void *v13; // eax@4
            IQueueVtbl *v14; // eax@4

            TS_SC_WATCH_BOOTH::TS_SC_WATCH_BOOTH((v2 - 44));
            v3 = *(v2 + 12);
            *(v2 - 37) = (**v3)(*(v2 + 12));
            *(v2 - 33) = *(v3 + 4484);
            v4 = StructPlayer::GetBoothItemList(v3);
            v5 = v4;
            v6 = std::vector<ArPosition_std::allocator<ArPosition>>::size(v4);
            *(v2 - 32) = v6;
            *(v2 - 44) += 75 * v6;
            v7 = IQueue::MakeQueue(*(v2 - 44), 0);
            *(v2 + 12) = v7;
            v8 = v7->vfptr;
            *(v2 - 4) = 0;
            (v8->Write)(v7);
            std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                (v2 - 28),
                v5->_Myfirst,
                &v5->baseclass_0.___u0.baseclass_0);
            *(v2 - 20) = *(v2 - 28);
            *(v2 - 16) = *(v2 - 24);
            while ( 1 )
            {
                std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                    (v2 - 28),
                    v5->_Mylast,
                    &v5->baseclass_0.___u0.baseclass_0);
                if ( std::_Vector_const_iterator<X2D::Point<float>_std::allocator<X2D::Point<float>>>::operator__(
                         (v2 - 20),
                         (v2 - 28)) )
                    break;
                v9 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v2 - 20));
                fillItemBaseInfo((v2 - 120), *v9);
                v10 = LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v2 - 20))->end.y);
                *(v2 - 104) = v10;
                *(v2 - 100) = HIDWORD(v10);
                v11 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_((v2 - 20));
                *(v2 - 53) = LODWORD(v11->end.z);
                *(v2 - 49) = LODWORD(v11->end.face);
                (v7->vfptr->Write)(v7);
                std::_Vector_const_iterator<StructCreature::HateModifier_std::allocator<StructCreature::HateModifier>>::operator__((v2 - 20));
            }
            v12 = *(v2 - 44);
            v13 = v7->vfptr->GetBuf(v7);
            PendStream(*(v2 + 8), v13, v12);
            v14 = v7->vfptr;
            *(v2 - 4) = -1;
            (v14->__vecDelDtor)(v7);
*/
        }

        public static void SendCantAttackMsg(Player pPlayer, uint attacker_handle, uint target_handle, int reason)
        {
            if (pPlayer == null || pPlayer.Connection == null)
                return;

            PacketOut pak = new PacketOut((ushort)ClientOutPackets.CantAttack);
            pak.WriteUInt32(attacker_handle);
            pak.WriteUInt32(target_handle);
            pak.WriteInt32(reason);
            pPlayer.Connection.SendTCP(pak);
        }

        public static void SendChatMessage(bool bLock, int nChatType, string szSenderName, Player target, string szString, uint len)
        {
            SendChatMessage(bLock, nChatType, szSenderName, target.m_hHandle, szString, len);
        }

        public static void SendChatMessage(bool bLock, int nChatType, string szSenderName, string szTarget, string szString, uint len)
        {
            Player sender = Player.get((uint)Player.FindPlayer(szSenderName)) as Player;
            Player target = Player.get((uint)Player.FindPlayer(szTarget)) as Player;
            if (target != null)
            {
                SendChatMessage(bLock, nChatType, szSenderName, target.GetHandle(), szString, len);
                if (sender != null)
                {
                    Messages.SendResult(sender.Connection, 20, 0, 0);
                }
            }
            else
            {
                if (sender != null)
                {
                    Messages.SendResult(sender.Connection, 20, 1, 0);
                }
            }
        }

        public static void SendChatMessage(bool bLock, int nChatType, string szSenderName, uint target, string szString, uint len)
        {
            int sl = (int)len;
            if (sl == 0)
            {
                sl = szString.Length;
            }
            if (len <= 30000)
            {
                PacketOut po = new PacketOut((ushort)ClientOutPackets.Chat);
                po.FillString(szSenderName, 21);
                po.WriteUInt16((ushort)(sl + 1));
                po.WriteByte((byte)nChatType);
                po.WriteString(szString);
                if (po.Position <= 16384)
                {
                    if (bLock)
                        SendChatMessageWithLock(target, po);
                    else
                        SendChatMessageWithoutLock(target, po);
                }
                else
                {
                    Globals.Log.Error("SendChatMessage +¦++-");
                }
            }
        }

        public static void SendChatMessageWithLock(uint target, PacketOut pMsg)
        {
            SendChatMessageWithLockArObjectFunctor fn = new SendChatMessageWithLockArObjectFunctor();
            fn.msg = pMsg;

            Player.DoPlayer(target, fn);
        }

        public static void SendChatMessageWithoutLock(uint hTarget, PacketOut pMsg)
        {
            Player player = Player.get(hTarget) as Player;
            if (player != null)
            {
                player.Connection.SendTCP(pMsg);
            }
        }

        public static void SendCompeteAnswer(Player pPlayer, sbyte nCompeteType, sbyte nAnswerType, string szRequestee)
        {
/*
            TS_SC_COMPETE_ANSWER msg; // [sp+8h] [bp-2Ch]@2
            unsigned int v5; // [sp+30h] [bp-4h]@1
            int v6; // [sp+34h] [bp+0h]@1

            v5 = &v6 ^ __security_cookie;
            if ( pPlayer )
            {
                TS_SC_COMPETE_ANSWER::TS_SC_COMPETE_ANSWER(&msg);
                msg.compete_type = nCompeteType;
                msg.answer_type = nAnswerType;
                strncpy_s(msg.requestee, 0x1Fu, szRequestee, 0x1Eu);
                PendMessage(&pPlayer->baseclass_0.baseclass_0.baseclass_0, &msg.baseclass_0);
            }
*/
        }

        public static void SendCompeteCountdown(Player pPlayer, sbyte nCompeteType, string szCompetitor, uint hCompetitor)
        {
/*
            TS_SC_COMPETE_COUNTDOWN msg; // [sp+8h] [bp-30h]@2
            unsigned int v5; // [sp+34h] [bp-4h]@1
            int v6; // [sp+38h] [bp+0h]@1

            v5 = &v6 ^ __security_cookie;
            if ( pPlayer )
            {
                TS_SC_COMPETE_COUNTDOWN::TS_SC_COMPETE_COUNTDOWN(&msg);
                msg.compete_type = nCompeteType;
                strncpy_s(msg.competitor, 0x1Fu, szCompetitor, 0x1Eu);
                msg.handle_competitor = hCompetitor;
                PendMessage(&pPlayer->baseclass_0.baseclass_0.baseclass_0, &msg.baseclass_0);
            }
*/
        }

        public static void SendCompeteEnd(Player pPlayer, sbyte nCompeteType, sbyte nEndType, string szWinner, string szLoser)
        {
/*
            TS_SC_COMPETE_END msg; // [sp+Ch] [bp-4Ch]@2
            unsigned int v6; // [sp+54h] [bp-4h]@1
            int v7; // [sp+58h] [bp+0h]@1

            v6 = &v7 ^ __security_cookie;
            if ( pPlayer )
            {
                TS_SC_COMPETE_END::TS_SC_COMPETE_END(&msg);
                msg.compete_type = nCompeteType;
                msg.end_type = nEndType;
                strncpy_s(msg.winner, 0x1Fu, szWinner, 0x1Eu);
                strncpy_s(msg.loser, 0x1Fu, szLoser, 0x1Eu);
                PendMessage(&pPlayer->baseclass_0.baseclass_0.baseclass_0, &msg.baseclass_0);
            }
*/
        }

        public static void SendCompeteRequest(Player pPlayer, sbyte nCompeteType, string szRequester)
        {
//             TS_SC_COMPETE_REQUEST msg; // [sp+8h] [bp-2Ch]@2
//             unsigned int v4; // [sp+30h] [bp-4h]@1
//             int v5; // [sp+34h] [bp+0h]@1
// 
//             v4 = &v5 ^ __security_cookie;
//             if ( pPlayer )
//             {
//                 TS_SC_COMPETE_REQUEST::TS_SC_COMPETE_REQUEST(&msg);
//                 msg.compete_type = nCompeteType;
//                 strncpy_s(msg.requester, 0x1Fu, szRequester, 0x1Eu);
//                 PendMessage(&pPlayer->baseclass_0.baseclass_0.baseclass_0, &msg.baseclass_0);
//             }
        }

        public static void SendCompeteStart(Player pPlayer, sbyte nCompeteType, string szCompetitor)
        {
//             TS_SC_COMPETE_START msg; // [sp+8h] [bp-2Ch]@2
//             unsigned int v4; // [sp+30h] [bp-4h]@1
//             int v5; // [sp+34h] [bp+0h]@1
// 
//             v4 = &v5 ^ __security_cookie;
//             if ( pPlayer )
//             {
//                 TS_SC_COMPETE_START::TS_SC_COMPETE_START(&msg);
//                 msg.compete_type = nCompeteType;
//                 strncpy_s(msg.competitor, 0x1Fu, szCompetitor, 0x1Eu);
//                 PendMessage(&pPlayer->baseclass_0.baseclass_0.baseclass_0, &msg.baseclass_0);
//             }
        }

        public static void SendCreatureEquipMessage(Player player, bool bShowDialog)
        {
            if(player == null || player.Connection == null)
                return;

            PacketOut pak = new PacketOut(ClientOutPackets.EquipSummon);
            pak.WriteByte((byte)(bShowDialog ? 1 : 0));
            for(int i = 0; i < 6; ++i)
            {
                if(player.m_aBindSummonCard[i] != null)
                {
//                    pak.WriteUInt32(0);
                    pak.WriteUInt32(player.m_aBindSummonCard[i].m_hHandle);
                }
                else
                {
                    pak.WriteUInt32(0);
                }
            }

            player.Connection.SendTCP(pak);
        }

        public static void SendDenialsList(Player player)
        {
            /*
                        int v1; // ebp@0
                        StructPlayer *v2; // esi@1
                        const char *v3; // eax@1

                        v2 = *(StructPlayer **)(v1 + 8);
                        std::basic_string<char_std::char_traits<char>_std::allocator<char>>::basic_string<char_std::char_traits<char>_std::allocator<char>>(
                        (std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)(v1 - 44),
                        "DLIST|");
                        *(_DWORD *)(v1 - 4) = 0;
                        *(_DWORD *)(v1 - 48) = v1 - 44;
                        *(_DWORD *)(v1 - 52) = &::::DenialListEnumerator::_vftable_;
                        StructPlayer::DoEachDenial(v2, (StructPlayer::FriendDenialFunctor *)(v1 - 52));
                        v3 = *(const char **)(v1 - 40);
                        if ( *(_DWORD *)(v1 - 20) < 0x10u )
                        v3 = (const char *)(v1 - 40);
                        SendChatMessage(0, 140, "@FRIEND", v2, v3, 0);
                        std::basic_string<char_std::char_traits<char>_std::allocator<char>>::_Tidy(
                        (std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)(v1 - 44),
                        1,
                        0);
            */
        }

        public static void SendDialogMessage(Player pPlayer, uint npc_handle, int type, string szTitle, string szText, string szMenu)
        {
            if (pPlayer == null || pPlayer.Connection == null)
                return;

            PacketOut pak = new PacketOut((ushort)ClientOutPackets.DialogMessage);

            pak.WriteInt32(type);
            pak.WriteUInt32(npc_handle);
            pak.WriteInt16((short)szTitle.Length);
            pak.WriteInt16((short)szText.Length);
            pak.WriteInt16((short)szMenu.Length);
            pak.WriteStringBytes(szTitle);
            pak.WriteStringBytes(szText);
            pak.WriteStringBytes(szMenu);
            pPlayer.Connection.SendTCP(pak);
        }

        public static void SendDisconnectDesc(TCPConnection pConn, int eDisconnectionDesc)
        {
            if (pConn == null)
                return;

            PacketOut pak = new PacketOut((ushort)ClientOutPackets.DisconnectDesc);
            pak.WriteByte((byte) eDisconnectionDesc);
            pConn.SendTCP(pak);
        }

        public static void SendDropResult(Player pClient, uint ItemHandle, bool bIsSuccess)
        {
/*
            TS_SC_DROP_RESULT msg; // [sp+0h] [bp-Ch]@1

            TS_SC_DROP_RESULT::TS_SC_DROP_RESULT(&msg);
            msg.item_handle = ItemHandle;
            msg.isAccepted = bIsSuccess;
            PendMessage(&pClient->baseclass_0.baseclass_0.baseclass_0, &msg.baseclass_0);
*/
        }

        public static void sendEnterMessage(BaseObject client, BaseObject obj, bool bAbsolute)
        {
            SchedulerObject.Priority pri;
            if (obj == null)
                return;

            if (obj.m_nArObjectType == 1)
            {
                obj.bIsNearClient = true;
                if (obj.pending_priority == SchedulerObject.Priority.Null)
                    pri = obj.priority;
                else
                    pri = obj.pending_priority;
                if ((int)pri < 3)
                {
                    RappelzServer.Instance.SetObjectPriority(obj, SchedulerObject.Priority.Normal);
                }
            }
            RappelzServer.m_Intf.SendEnterMessage(client, obj);
        }

        public static void SendEnterMsg(Player client, GameObject obj)
        {
            //             void *v2; // ebx@1
            //             unsigned int v3; // eax@1
            //             char v4; // al@1
            //             ArSchedulerObjectVtbl *v5; // eax@1
            //             unsigned int v6; // eax@1
            //             GameObject *v7; // esi@1
            //             int v8; // eax@2
            //             int v9; // eax@3
            //             char *v10; // eax@5
            //             char v11; // al@5
            //             ArObject *v12; // eax@8
            //             ArObject *v13; // edi@13
            //             void *v14; // ebx@20
            //             FileLogHandler *v15; // eax@22
            //             int v16; // eax@26
            //             int v17; // eax@26
            //             int v18; // eax@30
            //             const char *v19; // eax@30
            //             const char *v20; // eax@32
            //             char v21; // al@32
            //             char v22; // al@32
            //             int v23; // eax@36
            //             ArMoveVector::MOVE_INFO *v24; // ST18_4@43
            //             unsigned int v25; // eax@43
            //             ArPosition pos; // [sp+24h] [bp-80h]@1
            //             std::_Vector_const_iterator<StructState,std::allocator<StructState> > it; // [sp+34h] [bp-70h]@1
            //             GameObject *pCreature; // [sp+3Ch] [bp-68h]@2
            //             std::_Vector_const_iterator<unsigned int,std::allocator<unsigned int> > this; // [sp+40h] [bp-64h]@1
            //             bool bIsNeedStateNotify; // [sp+4Bh] [bp-59h]@2
            //             TS_WEAR_INFO wearInfo; // [sp+4Ch] [bp-58h]@1
            //             char buf[1024]; // [sp+190h] [bp+ECh]@1
            //             unsigned int v33; // [sp+590h] [bp+4ECh]@1
            // 
            //             v2 = pObj;
            //             it._Myptr = pClient;
            //             this._Myptr = pObj;
            //             TS_ENTER::TS_ENTER(buf);
            EnterPacketSC enter = new EnterPacketSC();
            PacketOut packet = new PacketOut((ushort)ClientOutPackets.Enter);
            uint ct = Globals.GetArTime();
            ArPosition pos = obj.GetCurrentPosition(ct);
            enter.layer = obj.m_layer;
            enter.x = pos.x;
            enter.y = pos.y;
            enter.z = pos.z;
            enter.handle = obj.m_hHandle;

            GameObject o = GameObject.raw_get(obj.m_hHandle);
            Creature cr = o as Creature;
            if(cr != null)
                Globals.Log.Trace("Entering Layer {0} x: {1} y: {2}: {3}", cr.m_layer,cr.region_x, cr.region_y, cr.GetName());
            if (o == null)
                return;

            Creature pCreature = obj as Creature;
            bool bIsNeedStateNotify = false;

            if(obj.IsItem())
            {
                enter.type = (byte)EnterPacketSC.MainType.StaticObject;
                enter.ObjType = (byte)EnterPacketSC.SubType.Item;
                enter.WriteToPacket(packet);
                Item item = (Item)obj;
                EnterPacketSC.ItemInfo item_info = new EnterPacketSC.ItemInfo();
                item_info.code = new c_encint(item.m_Instance.Code);
                item_info.cnt = item.m_Instance.nCount;
                item_info.pick_up_order.drop_time = item.m_nDropTime;
                for (int i = 0; i < 3; ++i)
                {
                    item_info.pick_up_order.nPartyID[i] = item.m_ItemPickupOrder.nPartyID[i];
                    item_info.pick_up_order.hPlayer[i] = item.m_ItemPickupOrder.hPlayer[i];
                }
                item_info.WriteToPacket(packet);
            }
            else if (obj.IsSkillProp())
            {
                enter.type = (byte)EnterPacketSC.MainType.StaticObject;
                enter.ObjType = (byte)EnterPacketSC.SubType.SkillProp;
                enter.WriteToPacket(packet);
                SkillProp skill_prop = (SkillProp)obj;
                EnterPacketSC.SkillInfo skill_info = new EnterPacketSC.SkillInfo();
                skill_info.caster = skill_prop.m_hCaster;
                skill_info.skill_num = skill_prop.m_Skill.m_SkillBase.uid;
                skill_info.start_time = skill_prop.m_Info.m_nStartTime;
                skill_info.WriteToPacket(packet);

            }
            else if (obj.IsFieldProp())
            {
                enter.type = (byte)EnterPacketSC.MainType.StaticObject;
                enter.ObjType = (byte)EnterPacketSC.SubType.FieldProp;
                enter.WriteToPacket(packet);
                FieldProp f_prop = (FieldProp)obj;
                EnterPacketSC.FieldPropInfo fp_info = new EnterPacketSC.FieldPropInfo();

                fp_info.prop_id = f_prop.m_PropInfo.nPropId;
                fp_info.fZOffset = f_prop.m_PropInfo.fZOffset;
                fp_info.fRotateX = f_prop.m_PropInfo.fRotateX;
                fp_info.fRotateY = f_prop.m_PropInfo.fRotateY;
                fp_info.fRotateZ = f_prop.m_PropInfo.fRotateZ;
                fp_info.fScaleX = f_prop.m_PropInfo.fScaleX;
                fp_info.fScaleY = f_prop.m_PropInfo.fScaleY;
                fp_info.fScaleZ = f_prop.m_PropInfo.fScaleZ;
                fp_info.bLockHeight = f_prop.m_PropInfo.bLockHeight;
                fp_info.fLockHeight = f_prop.m_PropInfo.fLockHeight;
                fp_info.WriteToPacket(packet);
            }
            else if (obj.IsPlayer())
            {
                enter.type = (byte)EnterPacketSC.MainType.Player;
                enter.ObjType = (byte)EnterPacketSC.SubType.Player;
                enter.WriteToPacket(packet);
                Player player = obj as Player;
                EnterPacketSC.PlayerInfo player_info = new EnterPacketSC.PlayerInfo();

                player_info.hp = player.m_nHP;
                player_info.max_hp = player.m_nMaxHP;
                player_info.mp = player.m_fMP;
                player_info.max_mp = player.m_nMaxMP;
                player_info.level = player.m_nLevel;
                player_info.race = (byte)player.m_nRace;
                player_info.skin_color = player.GetSkinColor();
                player_info.szName = player.GetName();
                player_info.sex = (byte)player.m_nSex;
                if (player.m_nRace == 0 || player.m_nSex == 0)
                {
                    Globals.Log.Error("TS_ENTER: Invalid object info - Position: ({0}, {1}, {2}) / Handle: {3}", enter.x, enter.y, enter.z, enter.handle);
                    return;
                }
                player_info.face_direction = player.mv.face;
                player_info.is_first_enter = (player.m_StatusFlag & Creature.StatusFlags.FirstEnter) != 0;
                player_info.energy = player.m_nEnergy;
                player_info.faceId = player.m_nBaseModelId[1];
                player_info.hairId = player.m_nBaseModelId[0];
                player_info.face = player.m_FaceScars;
                player_info.hair_cut = player.m_HairCut;
                player_info.hair_dye = player.m_HairDye;
                player_info.unk1 = player.m_Unk1;
                player_info.job_id = (ushort)player.GetJobId();
                player_info.status = GetStatusCode(player, client);
                player_info.ride_handle = player.GetRideHandle();
                if (player_info.ride_handle != 0)
                {
                    SendEnterMsg(client, player.GetRideObject());
                }
                if (player.m_vStateList.Count > 0)
                {
                    //.pCreature = obj;
                    bIsNeedStateNotify = true;
                }
                player_info.guild_id = player.m_nGuildId;
                player_info.WriteToPacket(packet);
            }
            else if (obj.IsNPC())
            {
                enter.type = (byte)EnterPacketSC.MainType.NPC;
                enter.ObjType = (byte)EnterPacketSC.SubType.NPC;

                NPC npc = (NPC)obj;
                EnterPacketSC.NPCInfo npc_info = new EnterPacketSC.NPCInfo();

                npc_info.face_direction = npc.mv.face;
                npc_info.npc_id = new c_encint(npc.m_BaseInfo.id);

                npc_info.mp = 0;
                npc_info.max_mp = 0;
                npc_info.hp = 100;
                npc_info.max_hp = 100;
                npc_info.level = npc.GetLevel();
                npc_info.skin_color = npc.GetSkinColor();
                npc_info.is_first_enter = false;
                npc_info.energy = npc.m_nEnergy;
                npc_info.race = 0xac;
                npc_info.status = GetStatusCode(npc, client);

                enter.WriteToPacket(packet);
                npc_info.WriteToPacket(packet);
            }
            else if (obj.IsMonster())
            {
                enter.type = (byte)EnterPacketSC.MainType.NPC;
                enter.ObjType = (byte)EnterPacketSC.SubType.Mob;

                Monster mob = (Monster)obj;
                EnterPacketSC.MonsterInfo mob_info = new EnterPacketSC.MonsterInfo();

                mob_info.face_direction = mob.mv.face;
                mob_info.monster_id = new c_encint(bits_scramble(mob.GetMonsterId()));
                mob_info.race = mob.GetRace();
                mob_info.hp = mob.m_nHP;
                mob_info.max_hp = mob.m_nMaxHP;
                mob_info.mp = mob.m_fMP;
                mob_info.max_mp = mob.m_nMaxMP;
                mob_info.level = mob.GetLevel();
                mob_info.skin_color = mob.GetSkinColor();
                mob_info.is_first_enter = (mob.m_StatusFlag & Creature.StatusFlags.FirstEnter) != 0;
                mob_info.energy = mob.m_nEnergy;
                mob_info.is_tamed = mob.GetTamer() != 0;
                mob_info.status = GetStatusCode(mob, client);

                enter.WriteToPacket(packet);
                mob_info.WriteToPacket(packet);
            }
            else if (obj.IsSummon())
            {
                enter.type = (byte)EnterPacketSC.MainType.NPC;
                enter.ObjType = (byte)EnterPacketSC.SubType.Summon;

                Summon pSummon = obj as Summon;

                EnterPacketSC.SummonInfo summon_info = new EnterPacketSC.SummonInfo();

                summon_info.face_direction = pSummon.mv.face;
                summon_info.summon_code = new c_encint(pSummon.GetSummonCode());
                summon_info.master_handle = pSummon.m_master.m_hHandle;
                summon_info.szName = pSummon.GetName();
                summon_info.race = pSummon.GetRace();
                summon_info.hp = pSummon.m_nHP;
                summon_info.max_hp = pSummon.m_nMaxHP;
                summon_info.mp = pSummon.m_fMP;
                summon_info.max_mp = pSummon.m_nMaxMP;
                summon_info.level = pSummon.GetLevel();
                summon_info.skin_color = pSummon.GetSkinColor();
                summon_info.skinNum = (uint)(pSummon.m_item.m_Instance.nEnhance > 0 ? 1 : 0);
                summon_info.is_first_enter = (pSummon.m_StatusFlag & Creature.StatusFlags.FirstEnter) != 0;
                summon_info.energy = pSummon.m_nEnergy;
                summon_info.status = GetStatusCode(pSummon, client);

                enter.WriteToPacket(packet);
                summon_info.WriteToPacket(packet);
            }
            else if(obj.IsPet())
            {
                enter.type = (byte)EnterPacketSC.MainType.NPC;
                enter.ObjType = (byte)EnterPacketSC.SubType.Pet;

                Pet pPet = obj as Pet;

                EnterPacketSC.PetInfo pet_info = new EnterPacketSC.PetInfo();

                pet_info.face_direction = pPet.mv.face; // 30
                pet_info.pet_code = new c_encint(pPet.m_ContentInfo.uid);
                pet_info.master_handle = pPet.m_master.m_hHandle;
                pet_info.szName = pPet.GetName();
                pet_info.skin_color = 0;//&buf[55] = 0;
                pet_info.race = pPet.GetRace(); //54
                pet_info.hp = 100;
                pet_info.mp = 100;
                pet_info.max_hp = 100;
                pet_info.max_mp = 100;
                pet_info.level = 1;
                pet_info.is_first_enter = (pPet.m_StatusFlag & Creature.StatusFlags.FirstEnter) != 0;
                pet_info.energy = 0;
                pet_info.status = GetStatusCode(pPet, client);
                enter.WriteToPacket(packet);
                pet_info.WriteToPacket(packet);
            }
            else if (obj.IsRoamer())
            {
                return;
            }

            client.Connection.SendTCP(packet);

            if (obj.m_nArObjectType != 0 && obj.mv.bIsMoving && obj.bIsInWorld)
                SendMoveMsg(client, obj);
            if (enter.type == (byte)EnterPacketSC.MainType.Player)
            {
                PacketOut packet2 = new PacketOut((ushort)ClientOutPackets.WearMessage);
                GetWearMsg((Creature)obj, packet2);
                client.Connection.SendTCP(packet2);
            }
            if (bIsNeedStateNotify)
            {
                if (pCreature != null)
                {
                    foreach(State s in pCreature.m_vStateList)
                    {
                        Messages.SendStateMessage(client, pCreature.m_hHandle, s, false);
                    }
                }
            }
        }

        public static void SendExpMsg(Player player, Creature creature)
        {
            PacketOut packet = new PacketOut((ushort)ClientOutPackets.ExpMessage);
            packet.WriteUInt32(creature.m_hHandle);
            packet.WriteInt64(creature.m_nEXP);
            packet.WriteInt64(creature.m_nJobPoint);
            player.Connection.SendTCP(packet);
        }

        public static void SendFriendsList(Player player)
        {
            /*
                        int v1; // ebp@0
                        StructPlayer *v2; // esi@1
                        ArSchedulerObjectVtbl *v3; // eax@1
                        const char *v4; // eax@1

                        v2 = *(StructPlayer **)(v1 + 8);
                        std::basic_string<char_std::char_traits<char>_std::allocator<char>>::basic_string<char_std::char_traits<char>_std::allocator<char>>(
                        (std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)(v1 - 44),
                        "FLIST|");
                        v3 = v2->baseclass_0.baseclass_0.baseclass_0.baseclass_0.vfptr;
                        *(_DWORD *)(v1 - 4) = 0;
                        *(_DWORD *)(v1 - 48) = v3[3].GetHandle((ArSchedulerObject *)v2);
                        *(_DWORD *)(v1 - 52) = v1 - 44;
                        *(_DWORD *)(v1 - 56) = &::::FriendListEnumerator::_vftable_;
                        StructPlayer::DoEachFriend(v2, (StructPlayer::FriendDenialFunctor *)(v1 - 56));
                        v4 = *(const char **)(v1 - 40);
                        if ( *(_DWORD *)(v1 - 20) < 0x10u )
                        v4 = (const char *)(v1 - 40);
                        SendChatMessage(0, 140, "@FRIEND", v2, v4, 0);
                        std::basic_string<char_std::char_traits<char>_std::allocator<char>>::_Tidy(
                        (std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)(v1 - 44),
                        1,
                        0);
            */
        }

        public static void SendGameTime(GameObject client)
        {
            Player p = client as Player;
            if (p == null)
                return;
            PacketOut packet = new PacketOut((ushort)ClientOutPackets.GameTime);
            packet.WriteUInt32(Globals.GetArTime());
            packet.WriteInt64(Globals.GetUnixTimestampInt64());
            p.Connection.SendTCP(packet);
        }

        public static void SendGlobalChatMessage(int ChatType, string szSenderName, string szString, uint len)
        {
            PacketOut pak = new PacketOut(ClientOutPackets.Chat);
            pak.FillString(szSenderName, 21);
            pak.WriteInt16((short)szString.Length);
            pak.WriteByte((byte)ChatType);
            pak.WriteString(szString);

            if (szString.Length < 16000)
            {
                SendGlobalChatMessagArObjectFunctor _sender = new SendGlobalChatMessagArObjectFunctor();
                _sender.msg = pak;
                Player.DoEachPlayer(_sender);

                Player p = Player.get((uint)Player.FindPlayer(szSenderName)) as Player;
                if (p != null)
                    SendResult(p, 20, 0, 0);
            }
            else
            {
//                 v6 = FileLogHandler::GetFileLogHandler();
//                 (v6->vfptr->LogString)(v6, "SendGlobalChatMessage +¦++-", msg.baseclass_0.size);
//                 v7 = XConsole::Inst(0);
//                 XConsole::Printf(v7, "SendGlobalChatMessage +¦++-");
            }
        }

        public static void SendGoldChaosUpdateMsg(Player player)
        {
            PacketOut packet = new PacketOut((ushort)ClientOutPackets.GoldChaosUpdateMessage);
            packet.WriteInt64(player.m_nGold);
            packet.WriteInt32(player.m_nChaos);
            player.Connection.SendTCP(packet);
        }

        public static void SendGuildChatMessage(string szSender, int nGuildID, string szString, uint len)
        {
            SendGuildChatMessage(11, szSender, nGuildID, szString, len);
        }

        public static void SendGuildChatMessage(int nChatType, string szSender, int nGuildID, string szString, uint len)
        {
//             GuildManager *v5; // eax@1
//             SendGuildChatMessage::__l2::myGuildFunctor _fo; // [sp+0h] [bp-10h]@1
// 
//             ::::myGuildFunctor::myGuildFunctor(&_fo, szSender, szString, nChatType);
//             v5 = GuildManager::GetInstance();
//             GuildManager::DoEachMember(v5, nGuildID, &_fo.baseclass_0);
        }

        public static void SendGuildInfo(Player pPlayer)
        {
            List<GuildManager.GuildMemberTag> vList = new List<GuildManager.GuildMemberTag>();

            if (pPlayer.m_nGuildId != 0)
            {
                GuildManager.GuildInfo ginfo = GuildManager.Instance.getGuildInfo(pPlayer.m_nGuildId);
                string buff = String.Format("GINFO|{0}|{1}|{2}|1|{3}|0|0|{4}", pPlayer.m_nGuildId, ginfo.strGuildName, ginfo.strLeaderName, ginfo.strNotice, ginfo.strURL);

                SendChatMessage(false, 110, "@GUILD", pPlayer.m_hHandle, buff,0);


                buff = String.Format("GPERMISSON|TopDog|529|R5555|0|R4444|0|R3333|0|R2222|0|R1111|0|");
                SendChatMessage(false, 110, "@GUILD", pPlayer.m_hHandle, buff, 0);

                buff = String.Format("GADV|0|-1325990124||");
                SendChatMessage(false, 110, "@GUILD", pPlayer.m_hHandle, buff, 0);

                SendGuildInfoFunctor fn = new SendGuildInfoFunctor();
                fn.m_pPlayer = pPlayer;
                GuildManager.Instance.DoEachMember(pPlayer.m_nGuildId, fn);

                GuildManager.Instance.GetOfflineMember(pPlayer.m_nGuildId, vList);

                foreach (GuildManager.GuildMemberTag mt in vList)
                {
                    buff = String.Format("GMEMBER|0|{0}|{1}|{2}|{3}|0|0|0|0|0", mt.strName, mt.nLevel, mt.nJobId, mt.nPermission);
                    SendChatMessage(false, 110, "@GUILD", pPlayer.m_hHandle, buff,0);

                    buff = String.Format("MEMO|{0}|{1}|", mt.strName, mt.strMemo);
                    Messages.SendChatMessage(false, 110, "@GUILD", pPlayer.m_hHandle, buff, 0);

                }
            }
        }

        public static void SendGuildNotify(Player pPlayer)
        {
            string szBuf = String.Format("GCHANGE|{0}|{1}", pPlayer.m_nGuildId, (int)pPlayer.m_hHandle);
            SendLocalChatMessage(110, (uint)(pPlayer.mv.x / GameContent.g_nRegionSize),(uint)(pPlayer.mv.y / GameContent.g_nRegionSize),
                pPlayer.m_layer, "@GUILD", szBuf, 0);
        }

        public static void SendHPMPMsg(Player player, Creature creature, int add_hp, float add_mp, bool need_to_display)
        {
            PacketOut o = new PacketOut(509);
            o.WriteUInt32(creature.m_hHandle);
            o.WriteInt32(add_hp);
            o.WriteInt32(creature.m_nHP);
            o.WriteInt32(creature.m_nMaxHP);
            o.WriteInt32((int)add_mp);
            o.WriteInt32((int)creature.m_fMP);
            o.WriteInt32(creature.m_nMaxMP);
            o.WriteByte((byte)(need_to_display ? 1 : 0));
            player.Connection.SendTCP(o);
        }

        public static void SendHuntaholicHuntingScore(Player pPlayer, int nHuntaholicID, int nPersonalKillCount, int nPersonalScore, int nKillCount, int nScore, double fPointAdvantage, double fPointRate, int nGainPoint, sbyte nResultType)
        {
//             long double v10; // st7@2
//             TS_SC_HUNTAHOLIC_HUNTING_SCORE msg; // [sp+0h] [bp-30h]@2
// 
//             if ( pPlayer )
//             {
//                 TS_SC_HUNTAHOLIC_HUNTING_SCORE::TS_SC_HUNTAHOLIC_HUNTING_SCORE(&msg);
//                 msg.huntaholic_id = nHuntaholicID;
//                 msg.personal_kill_count = nPersonalKillCount;
//                 msg.personal_score = nPersonalScore;
//                 msg.kill_count = nKillCount;
//                 msg.score = nScore;
//                 msg.point_advantage = *fPointAdvantage;
//                 v10 = *fPointRate;
//                 msg.gain_point = nGainPoint;
//                 msg.point_rate = v10;
//                 msg.result_type = nResultType;
//                 PendMessage(&pPlayer->baseclass_0.baseclass_0.baseclass_0, &msg.baseclass_0);
//             }
        }

//         public static void SendHuntaholicInstanceInfo(Player pPlayer, TS_HUNTAHOLIC_INSTANCE_INFO *info)
//         {
//             TS_SC_HUNTAHOLIC_INSTANCE_INFO msg; // [sp+8h] [bp-34h]@2
//             unsigned int v3; // [sp+38h] [bp-4h]@1
//             int v4; // [sp+3Ch] [bp+0h]@1
// 
//             v3 = &v4 ^ __security_cookie;
//             if ( pPlayer )
//             {
//                 TS_SC_HUNTAHOLIC_INSTANCE_INFO::TS_SC_HUNTAHOLIC_INSTANCE_INFO(&msg);
//                 memcpy_s(&msg.info, 0x26u, info, 0x26u);
//                 PendMessage(&pPlayer->baseclass_0.baseclass_0.baseclass_0, &msg.baseclass_0);
//             }
//         }

        public static void SendItemCoolTimeInfo(Player pPlayer)
        {
            if (pPlayer == null || pPlayer.Connection == null)
                return;

            uint ct = Globals.GetArTime();

            using (var pak = new PacketOut(ClientOutPackets.ItemCoolTime))
            {
                for(int i = 0; i < 40; ++i)
                {
                    int cool_time = (int)(pPlayer.GetItemCoolTime(i+1) - ct);
                    if(cool_time < 0) cool_time = 0;
                    pak.WriteInt32(cool_time);
                }
                pPlayer.Connection.SendTCP(pak);
            }
        }

        public static void SendItemCountMessage(Player pPlayer, Item pItem)
        {
            if (pPlayer == null || pPlayer.Connection == null)
                return;
            using (var pak = new PacketOut(ClientOutPackets.ItemCount))
            {
                pak.WriteUInt32(pItem.m_hHandle);
                pak.WriteInt64(pItem.m_Instance.nCount);
                pPlayer.Connection.SendTCP(pak);
            }
        }

        public static void SendItemDestroyMessage(Player pPlayer, Item pItem)
        {
            if (pPlayer == null || pPlayer.Connection == null)
                return;
            using (var pak = new PacketOut((ushort)ClientOutPackets.ItemDestroy))
            {
                pak.WriteUInt32(pItem.GetHandle());
                pPlayer.Connection.SendTCP(pak);
            }
        }

        public static void SendItemList(Player player, bool bIsStorage)
        {
            Item item;

            if (player.GetItemCount() > 0)
            {
                uint count = bIsStorage ? player.GetStorageItemCount() : player.GetItemCount();
                uint idx = 0;
                if (count != 0)
                {
                    do
                    {
                        PacketOut packet = new PacketOut((ushort)ClientOutPackets.Inventory);
                        uint lcnt = idx;
                        uint mcount = 200;
                        if (count - idx <= 200)
                            mcount = count - idx;

                        packet.WriteShort((ushort)mcount);

                        uint ltotal = idx + mcount;
                        if (idx < ltotal)
                        {
                            do
                            {
                                if (bIsStorage)
                                    item = player.GetStorageItem(lcnt);
                                else
                                    item = player.GetItem(lcnt);
                                fillItemInfo(packet, item);
                                ++lcnt;
                            }
                            while (lcnt < ltotal);
                        }
                        player.Connection.SendTCP(packet);
                        idx += 200;
                    }
                    while (idx < count);
                }
            }
        }

        public static void SendItemMessage(Player player, Item item)
        {
            if (player == null || player.Connection == null)
                return;

            PacketOut packet = new PacketOut((ushort)ClientOutPackets.Inventory);
            packet.WriteShort(1);
            fillItemInfo(packet, item);
            player.Connection.SendTCP(packet);
        }

        public static void SendItemWearInfoMessage(Player player, Creature target, Item item)
        {
            PacketOut packet = new PacketOut((ushort)ClientOutPackets.ItemWearInfoMessage);
            packet.WriteUInt32(item.m_hHandle);
            packet.WriteInt16((short)item.m_Instance.nWearInfo);
            packet.WriteUInt32((target != null) ? target.m_hHandle : 0);
            packet.WriteInt32(item.m_Instance.nEnhance);
            packet.WriteInt32((int)item.GetElementalEffectType());
            player.Connection.SendTCP(packet);
        }

        public static void SendJobInfo(Player player, Creature creature)
        {
            int job_id = creature.GetJobId();
            uint handle = creature.GetHandle();
            SendPropertyMessage(player, handle, "job", job_id);
            int job_level = creature.GetJobLevel();
            SendPropertyMessage(player, handle, "job_level", job_level);

            for (int i = 0; i < 3; ++i)
            {
                string buff = String.Format("job_{0}", i);
                job_id = creature.GetPrevJobId(i);
                SendPropertyMessage(player, handle, buff, job_id);
                buff = String.Format("jlv_{0}", i);
                job_level = creature.GetPrevJobLevel(i);
                SendPropertyMessage(player, handle, buff, job_level);

            }
        }

        public static void SendLeaveMsg(BaseObject client, BaseObject obj)
        {
            Player player = client as Player;
            if (player == null)
                return;

            if (GameObject.raw_get(obj.m_hHandle) != null)
            {
                Creature cr = obj as Creature;
                if (cr != null)
                    Globals.Log.Debug("Leaving: {0}", cr.GetName());

                PacketOut pak = new PacketOut((ushort)ClientOutPackets.Leave);
                pak.WriteUInt32(obj.m_hHandle);
                player.Connection.SendTCP(pak);
            }
        }

        public static void SendLevelMsg(Player player, Creature creature)
        {
            PacketOut packet = new PacketOut((ushort)ClientOutPackets.LevelMessage);
            packet.WriteUInt32(creature.m_hHandle);
            packet.WriteInt32(creature.m_nLevel);
            packet.WriteInt32(creature.m_nJobLevel);
            player.Connection.SendTCP(packet);
        }

        public static void SendLocalChatMessage(int nChatType, uint handle, string szString, uint len)
        {

// Data           :   ebp Relative, [0000400C], Param, Type: int, nChatType
// Data           :   ebp Relative, [00004010], Param, Type: unsigned int, handle
// Data           :   ebp Relative, [00004014], Param, Type: const char *, szString
// Data           :   ebp Relative, [00004018], Param, Type: unsigned int, len
// Data           :   ebp Relative, [FFFFFFD0], Local, Type: struct StructPlayer::iterator, pit
// Data           :   ebp Relative, [FFFFFFD8], Local, Type: struct TS_SC_CHAT_LOCAL, msg
// Data           :   ebp Relative, [FFFFFFB4], Local, Type: struct ArcadiaAutoLock, _lock
// Data           :   ebp Relative, [FFFFFFE8], Local, Type: struct StructCreature::iterator, cit
// Data           :   ebp Relative, [00000000], Local, Type: char[0x4000], pBuffer

            RLock rl;
            AutoLock al;
            
            Player p = Player.get(handle) as Player;

            if (p != null)
            {
                rl = RappelzServer.Instance._LockObjectWithVisibleRange(p);
                al = new AutoLock(rl.handle);

                PacketOut pak = new PacketOut(ClientOutPackets.ChatLocal);
                pak.WriteUInt32(handle);
                pak.WriteByte((byte)szString.Length);
                pak.WriteByte((byte)nChatType);
                pak.WriteString(szString);

                RappelzServer.Instance.Broadcast((uint)(p.mv.x / GameContent.g_nRegionSize),(uint)(p.mv.y / GameContent.g_nRegionSize),p.m_layer,pak);
                SendResult(p, 20, 0, 0);
//                ArcadiaAutoLock::_ArcadiaAutoLock(&_lock);
            }
            else
            {
//                 v5 = FileLogHandler::GetFileLogHandler();
//                 (v5->vfptr->LogString)(v5, "-++t¦--", handle);
//                 v6 = XConsole::Inst(0);
//                 XConsole::Printf(v6, "-++t¦--");
            }
        }

        public static void SendLocalChatMessage(int nChatType, uint rx, uint ry, byte layer, string szSenderName, string szString, uint len)
        {
            RLock rl = RappelzServer.Instance._Lock(rx,ry);
            AutoLock al = new AutoLock(rl.handle);

            PacketOut pak = new PacketOut(ClientOutPackets.Chat);

            pak.FillString(szSenderName, 21);
            pak.WriteInt16((short)szString.Length);
            pak.WriteByte((byte)nChatType);
            pak.WriteString(szString);

            if (szString.Length <  16300)
            {
                RappelzServer.Instance.Broadcast(rx,ry,layer,pak);
            }
//            ArcadiaAutoLock::_ArcadiaAutoLock(&_lock);
        }

        public static void SendLoginResult(TCPConnection conn, Player player, string szError)
        {
            if (String.IsNullOrEmpty(szError))
            {
                SendTimeSync(player);
                string lstr = String.Format("on_login('{0}')", player.m_hHandle);
                //                lstr = "on_login2(2)";
                //                v12 = RappelzServer.Instance.LockObjectWithVisibleRange(*(ArcadiaLock **)&msg.szName[15],(ArObject *)msg.cell_size,(const char *)msg.guild_id,*(_DWORD *)&strFirstLoginHandler);
                //                ArcadiaAutoLock.ArcadiaAutoLock(&_lock,v12);
                //                string lua_result;
                LuaVM.Instance.RunString(player, lstr);
                //                ArcadiaAutoLock::_ArcadiaAutoLock(&_lock);
                player.SetCurrentXY(player.mv.x, player.mv.y);

                using (var pak = new PacketOut((ushort)ClientOutPackets.LoginResult))
                {
                    pak.WriteInt16(0); // result
                    pak.WriteUInt32(player.m_hHandle);
                    pak.WriteFloat(player.mv.x);
                    pak.WriteFloat(player.mv.y);
                    pak.WriteFloat(player.mv.z);
                    pak.WriteByte(player.m_layer);
                    pak.WriteFloat(player.mv.face);
                    pak.WriteInt32(Globals.nRegionSize);
                    pak.WriteInt32(player.m_nHP);
                    pak.WriteInt32((int)player.m_fMP);
                    pak.WriteInt32(player.m_nMaxHP);
                    pak.WriteInt32((int)player.m_nMaxMP);
                    pak.WriteInt32(player.m_nHavoc);
                    pak.WriteInt32(player.m_nMaxHavoc);
                    pak.WriteInt32(player.m_nSex);
                    pak.WriteInt32(player.m_nRace);
                    pak.WriteUInt32(player.m_nSkinColor);
                    pak.WriteInt32(player.m_nBaseModelId[1]);
                    pak.WriteInt32(player.m_nBaseModelId[0]);
                    pak.FillString(player.m_szName, 19);
                    pak.WriteInt32(6); // cell size
                    pak.WriteInt32(player.GuildId);
                    player.Connection.SendTCP(pak);
                }

                player.SendCharacterInfo();
                if (!GameRule.bIsCashUsableServer)
                {
                    SendPropertyMessage(player, player.m_hHandle, "client_info", player.m_strClientInfo);
                }
                if (player.PartyId != 0)
                {
                    string party_name = PartyManager.Instance.GetPartyName(player.PartyId);
                    PrintfPartyChatMessage(100, player.PartyId, "LOGIN|%s|%s|", party_name, player.m_hHandle);
                    BroadcastPartyMemberInfo(player.PartyId, player);
                    PartyManager.Instance.onLogin(player.PartyId, player);
                    SendPartyInfo(player);
                    //                    SendAttackTeamInfo(player);
                }
                if (player.GuildId != 0)
                {
                    string gname = GuildManager.Instance.GetGuildName(player.GuildId);
                    if (gname.Length > 0)
                    {
                        //                        PrintfGuildChatMessage(110, player.GuildId, "LOGIN|%s|%s|");
                        Messages.BroadcastGuildMemberInfo(player.GuildId, player);
                        GuildManager.Instance.onLogin(player.GuildId, player);
                        Messages.SendGuildInfo(player);
                    }
                }
                Messages.SendQuestList(player);
                Messages.SendFriendsList(player);
                Messages.SendDenialsList(player);
                Messages.SendStatusMessageToFriendOfPlayer(player, true);

                //                v42 = RappelzServer.Instance._LockObjectWithVisibleRange(*(ArcadiaLock **)&msg.szName[15],(ArObject *)msg.cell_size,(const char *)msg.guild_id,*(_DWORD *)&strFirstLoginHandler);
                //                ArcadiaAutoLock::ArcadiaAutoLock(&_lock,v42);
                player.SetContinuousPlayTime(player.GetContinuousPlayTime());
                Messages.SendPropertyMessage(player, player.m_hHandle, "playtime_limit1", GameRule.nMaxHealthyGameTime);
                Messages.SendPropertyMessage(player, player.m_hHandle, "playtime_limit2", GameRule.nMaxTiredGameTime);
                //                ArcadiaAutoLock::_ArcadiaAutoLock(&_lock);
                if (RankingManager.Instance.IsValidRankingScore(RankingManager.RankingType.RankingTypeDonationReward, player.SID))
                {
                    Messages.SendChatMessage(false, 20, "@NOTICE", player.m_hHandle, "@6748", 0);
                }

                if (GameRule.bUseLoginLogoutDebug)
                {
                    Globals.Log.Info("SendLoginResult ({0}, {1})", player.m_szName, player.AccountName);
                }
                if (player != null)
                {
                    if (player.Connection == null)
                        player.LogoutNow(3);
                }
            }
        }

        /// <summary>
        /// Sends a login packer to the auth server
        /// </summary>
        public static void SendLoginToAuth(string szAccount, long one_time_key)
        {
            if (GameRule.bUseLoginLogoutDebug)
                Globals.Log.Info("LoginLogout_Debug: SendLoginToAuth {0}", szAccount);

            PacketOut pak = new PacketOut((ushort)ServerOutPackets.ClientLogin);
            pak.FillString(szAccount, 61);
            pak.WriteInt64(one_time_key);

            AuthClientNetwork.Instance.SendMessage(pak);
        }

        /// <summary>
        /// Sends a logout packer to the auth server
        /// </summary>
        public static void SendLogoutToAuth(string szAccount, uint nContinuousPlayTime, int nCallerIdx)
        {
            if (GameRule.bUseLoginLogoutDebug)
            {
                Globals.Log.Info("LoginLogout_Debug : SendLogoutToAuth ({0}, {1})", szAccount, nCallerIdx);
            }

            PacketOut pak = new PacketOut((ushort)ServerOutPackets.ClientLogout);
            pak.FillString(szAccount, 61);
            pak.WriteUInt32(nContinuousPlayTime);

            AuthClientNetwork.Instance.SendMessage(pak);
        }


        public static void SendMarketInfo(Player pPlayer, uint npc_handle, MarketInfo pInfo)
        {
            if (pPlayer == null)
                return;

            PacketOut pak = new PacketOut(ClientOutPackets.MarketInfo);

            pPlayer.SetLastContact("market", pInfo.szMarketName);
            pak.WriteUInt32(npc_handle);
            pak.WriteUInt16((ushort)pInfo.vItemList.Count);

            foreach (MarketInfo.MarketTag mt in pInfo.vItemList)
            {
                pak.WriteInt32(mt.code);
                pak.WriteInt64(mt.price);
                pak.WriteInt32(mt.huntaholic_point);
                if (GameRule.nClientVersion >= 81)
                {
                    pak.WriteInt32(0); // ap points
                }
            }

            pPlayer.Connection.SendTCP(pak);
        }

        public static void SendMixResult(Player pClient, uint[] pHandle, uint count)
        {
            if (pClient == null)
                return;

            PacketOut pak = new PacketOut(ClientOutPackets.MixResult);
            pak.WriteUInt32(count);
            if(count > 0 && pHandle != null)
            {
                for(int i = 0; i < count;++i)
                {
                    pak.WriteUInt32(pHandle[i]);
                }
            }
            pClient.Connection.SendTCP(pak);
        }

        public static void SendMoveMsg(BaseObject client, BaseObject obj)
        {
            Player player = client as Player;
            if (player == null)
                return;

            if (obj.mv.ends.Count < 2000)
            {
                PacketOut pak = new PacketOut((ushort)ClientOutPackets.Move);
                pak.WriteUInt32(obj.lastStepTime);
                pak.WriteUInt32(obj.m_hHandle);
                pak.WriteByte(obj.m_layer);
                pak.WriteByte(obj.mv.speed);
                pak.WriteUInt16((ushort)obj.mv.ends.Count);

                foreach (ArMoveVector.MoveInfo pos in obj.mv.ends)
                {
                    pak.WriteFloat(pos.end.x);
                    pak.WriteFloat(pos.end.y);
                }

                player.Connection.SendTCP(pak);
            }
            else
            {
                Globals.Log.Error("SendMoveMsg: Too Many Steps! {0}", obj.mv.ends.Count);
            }
        }

        public static void SendNPCStatusInVisibleRange(Player pPlayer)
        {
            SendNPCStatusInVisibleRangeArObjectFunctor fn2 = new SendNPCStatusInVisibleRangeArObjectFunctor();
            fn2.pPlayer = pPlayer;
            fn2.pIntf = RappelzServer.m_Intf;
            SendNPCStatusInVisibleRangeArRegionFunctor fn = new SendNPCStatusInVisibleRangeArRegionFunctor();
            fn.pFo = fn2;

            RappelzServer.Instance.DoEachVisibleRegion((int)(pPlayer.mv.x / GameContent.g_nRegionSize), (int)(pPlayer.mv.y / GameContent.g_nRegionSize), pPlayer.m_layer, fn);
        }

        public static void SendOpenStorageMessage(Player pPlayer)
        {
            if (pPlayer == null || pPlayer.Connection == null)
                return;

            using(PacketOut pak = new PacketOut(ClientOutPackets.OpenStorage))
            {
                pPlayer.Connection.SendTCP(pak);
            }
        }

        public static void SendOpenUrl(Player player, string szUrl, bool bWaitForEventScene, int width, int height)
        {
            /*
                        unsigned __int16 v5; // ax@1
                        TS_SC_OPEN_URL msg; // [sp+8h] [bp-80h]@1
                        char szTmp[1024]; // [sp+1Ch] [bp-6Ch]@1
                        unsigned int v8; // [sp+41Ch] [bp+394h]@1

                        v8 = (unsigned int)&szTmp[108] ^ __security_cookie;
                        TS_SC_OPEN_URL::TS_SC_OPEN_URL(&msg);
                        msg.wait_for_event_scene = bWaitForEventScene;
                        msg.width = width;
                        msg.height = height;
                        strlen((char *)szUrl);
                        msg.url_len = v5;
                        msg.baseclass_0.size += v5;
                        if ( msg.baseclass_0.size <= 0x400 )
                        {
                            memcpy(&szTmp[18], (char *)szUrl, v5);
                            memcpy(szTmp, (char *)&msg, 0x12u);
                            PendStream(&pPlayer->baseclass_0.baseclass_0.baseclass_0, szTmp, msg.baseclass_0.size);
                        }
            */
        }

        public static void SendPartyChatMessage(string szSender, int nPartyID, string szString, uint len)
        {
            SendPartyChatMessage(10, szSender, nPartyID, szString, len);
        }

        public static void SendPartyChatMessage(int nChatType, string szSender, int nPartyID, string szString, uint len)
        {
            //             PartyManager *v5; // eax@1
            //             SendPartyChatMessage::__l2::myPartyFunctor _fo; // [sp+0h] [bp-10h]@1
            // 
            //             ::::myPartyFunctor::myPartyFunctor(&_fo, szSender, szString, nChatType);
            //             PartyManager.Instance.DoEachMember(nPartyID, &_fo.baseclass_0);
        }

        public static void SendPartyInfo(Player player)
        {
            if (player.PartyId != 0)
            {
                string leader = PartyManager.Instance.GetLeaderName(player.PartyId);
                string name = PartyManager.Instance.GetPartyName(player.PartyId);
                //                int min_lvl = PartyManager.Instance.GetMinLevel(player.PartyId);
                //                int max_lvl = PartyManager.Instance.GetMaxLevel(player.PartyId);
                //                int share_mode = PartyManager.Instance.GetShareMode(player.PartyId);

                //                string msg = String.Format("PINFO|%s|%s|%d|%d|%d|", leader, name, min_lvl, max_lvl, share_mode);
                //                 *(_DWORD *)(v1 - 56) = v1 - 44;
                //                 *(_DWORD *)(v1 - 60) = &::::myPartyMemberTagFunctor::_vftable_;
                // 
                //                 PartyManager.Instance.DoEachMemberTag(player.PartyId, (PartyManager::PartyMemberTagFunctor *)(v1 - 60));
                //                 v13 = *(const char **)(v1 - 40);
                //                 if ( *(_DWORD *)(v1 - 20) < 0x10u )
                //                     v13 = (const char *)(v1 - 40);
                //                SendChatMessage(0, 100, "@PARTY", player, msg, 0);
            }
        }

        public static void SendPartyPosition(Player pPlayer)
        {
//             int v1; // ebp@0
//             int v2; // esi@1
//             int v3; // edi@1
//             PartyManager *v4; // eax@2
// 
//             v2 = *(v1 + 8);
//             v3 = *(v2 + 4244);
//             if ( v3 )
//             {
//                 *(v1 - 48) = &::::myPartyFunctor::_vftable_;
//                 std::basic_string<char_std::char_traits<char>_std::allocator<char>>::basic_string<char_std::char_traits<char>_std::allocator<char>>((v1 - 44));
//                 *(v1 - 4) = 0;
//                 v4 = PartyManager::GetInstance();
//                 PartyManager::DoEachMember(v4, v3, (v1 - 48));
//                 PrintfChatMessage(0, 100, "@PARTY", v2, "PPOS|%s");
//                 std::basic_string<char_std::char_traits<char>_std::allocator<char>>::_Tidy((v1 - 44), 1, 0);
//             }
        }

        public static void SendPropertyMessage(Player player, uint handle, string szPropertyName, long value)
        {
            using (var pak = new PacketOut((ushort)ClientOutPackets.Property))
            {
                pak.WriteUInt32(handle);
                pak.WriteByte(1);
                pak.FillString(szPropertyName, 16);
                pak.WriteInt64(value);
                pak.FinalizeLengthAndChecksum();
                player.Connection.SendTCP(pak);
            }
        }

        public static void SendPropertyMessage(Player player, uint handle, string szPropertyName, string szValue)
        {
            using (var pak = new PacketOut((ushort)ClientOutPackets.Property))
            {
                pak.WriteUInt32(handle);
                pak.WriteByte(0);
                pak.FillString(szPropertyName, 16);
                pak.WriteInt64(0);
                pak.WriteString(szValue);
                pak.FinalizeLengthAndChecksum();
                player.Connection.SendTCP(pak);
            }
        }

        public static void SendQuestInformation(Player pPlayer, int code, int text)
        {
            string strButton;
            string strTrigger;
            int i = 0;
            int type = 3;

            // we need to get the type and progress from the 'text' param
            // if it is 0 then we are starting it
          
            NPC npc = GameObject.raw_get(pPlayer.GetLastContactLong("npc")) as NPC;
            if(npc == null)
            {
                //npc == Quest.GetQuestBase(code).
            }
            if (true/*npc != null*/)
            {
                int progress = 0;
                if (text != 0)
                {
                    progress = npc.GetProgressFromTextId(code, text);
                    if (progress == 1)
                        type = 7;
                    if (progress == 2)
                        type = 8;
                }
                else 
                {
                    if (pPlayer.IsStartableQuest(code, false))
                        progress = 0;
                    else
                        progress = pPlayer.IsFinishableQuest(code) ? 2 : 1;
                }
                Quest q = pPlayer.FindQuest(code);
                int textId = text;
                if(textId == 0)
                    textId = npc != null ? npc.GetQuestTextId(code, progress) : q.m_Instance.nStartID;
                if (npc == null)
                {
                    if(q.m_QuestBase.nEndType != 1 || progress != 2)
                    {
                        type = 7;
                        progress = 1;
                    }
                    else
                    {
                        QuestLink l = GameContent.GetQuestLink(code, q.m_Instance.nStartID);
                        if(l != null && l.nEndTextId != 0)
                            textId = l.nEndTextId;
                        type = 8;
                    }
                }
                pPlayer.SetDialogTitle(npc != null ? npc.GetName() : "", type);
                string buf = String.Format("QUEST|{0}|{1}", code, textId);
                pPlayer.SetDialogText(buf);
                QuestBaseServer rQuestBase = Quest.GetQuestBase(code);

                if (progress != 0)
                {
                    if (pPlayer.IsFinishableQuest(code))
                    {
                        for(i = 0; i < 6; i++)
                        {
                            if(rQuestBase.OptionalReward[i].nItemCode == 0)
                                break;

                            strTrigger = String.Format("end_quest( {0}, {1} )",code,i);
                            pPlayer.AddDialogMenu("NULL", strTrigger);
                        }
                        if(i != 0)
                        {
                            strButton = "REWARD";
                            strTrigger = rQuestBase.nCode.ToString();
                        }
                        else
                        {
                            strTrigger = String.Format("end_quest( {0}, -1 )",code);
                            pPlayer.AddDialogMenu("NULL",strTrigger);
                            strButton = "REWARD";
                            strTrigger = rQuestBase.nCode.ToString();
                        }
                    }
                    else
                    {
                        strButton = "OK";
                        strTrigger = "";
                    }
                }
                else
                {
                    strTrigger = String.Format("start_quest( {0}, {1} )", code,textId);
                    pPlayer.AddDialogMenu("START", strTrigger);
                    strTrigger = "";
                    strButton = "REJECT";
                }
                pPlayer.AddDialogMenu(strButton, strTrigger);
            }
        }

        public static void SendQuestList(Player player)
        {
            int cnt = player.m_QuestManager.m_vActiveQuest.Count;

            PacketOut packet = new PacketOut((ushort)ClientOutPackets.QuestList);
            packet.WriteInt32(cnt);
            SendQuestListFunctor fn = new SendQuestListFunctor(player, packet);
            player.m_QuestManager.DoEachActiveQuest(fn);
            player.Connection.SendTCP(packet);
        }

        public static void SendQuestMessage(int nChatType, Player pTarget, string szString, params object[] args)
        {
            string szBuf = String.Format(szString, args);
            SendChatMessage(true, nChatType, "@QUEST", pTarget, szBuf,0);
        }

        public static void SendQuestStatus(Player pPlayer, Quest pQuest)
        {
            PacketOut packet = new PacketOut((ushort)ClientOutPackets.QuestStatus);
            packet.WriteInt32(pQuest.m_Instance.Code);
            for(int i = 0; i < 6; ++i)
            {
                packet.WriteInt32(pQuest.m_Instance.nStatus[i]);
            }
            packet.WriteByte((byte) (pQuest.IsFinishable() ? 2 : 1));
            packet.WriteUInt32(pQuest.m_Instance.nTime);
            pPlayer.Connection.SendTCP(packet);
        }

        public static void SendRemovePetMessage(Player pPlayer, Pet pPet)
        {
//             TS_SC_REMOVE_PET_INFO msg; // [sp+0h] [bp-Ch]@1
// 
//             TS_SC_REMOVE_PET_INFO::TS_SC_REMOVE_PET_INFO(&msg);
//             msg.handle = (pPet->baseclass_0.baseclass_0.baseclass_0.baseclass_0.vfptr->GetHandle)();
//             PendMessage(&pClient->baseclass_0.baseclass_0.baseclass_0, &msg.baseclass_0);
        }

        public static void SendRemoveSummonMessage(Player pPlayer, Summon pSummon)
        {
            //             TS_SC_REMOVE_SUMMON_INFO msg; // [sp+0h] [bp-Ch]@1
            // 
            //             TS_SC_REMOVE_SUMMON_INFO::TS_SC_REMOVE_SUMMON_INFO(&msg);
            //             msg.card_handle = (**pSummon->m_pItem)();
            //             PendMessage(&pClient->baseclass_0.baseclass_0.baseclass_0, &msg.baseclass_0);
        }

        public static void SendResult(BaseObject pObj, ushort msg, ushort result, int value)
        {
            Player p = pObj as Player;
            if(p == null || p.Connection == null)
                return;
            using (var pak = new PacketOut((ushort)ClientOutPackets.MsgResult))
            {
                pak.WriteShort(msg);
                pak.WriteShort(result);
                pak.WriteInt32(value);
                pak.FinalizeLengthAndChecksum();
                p.Connection.SendTCP(pak);
            }
        }

        public static void SendResult(BaseObject pObj, ushort msg, ushort result, uint value)
        {
            Player p = pObj as Player;
            if (p == null || p.Connection == null)
                return;
            using (var pak = new PacketOut((ushort)ClientOutPackets.MsgResult))
            {
                pak.WriteShort(msg);
                pak.WriteShort(result);
                pak.WriteUInt32(value);
                pak.FinalizeLengthAndChecksum();
                p.Connection.SendTCP(pak);
            }
        }

        /// <summary>
        /// Sends a result packet to the game client
        /// </summary>
        public static void SendResult(TCPConnection client, ushort msg, ushort result, int value)
        {
            using (var pak = new PacketOut((ushort)ClientOutPackets.MsgResult))
            {
                pak.WriteShort(msg);
                pak.WriteShort(result);
                pak.WriteInt32(value);
                pak.FinalizeLengthAndChecksum();
                client.SendTCP(pak);
            }
        }

        /// <summary>
        /// Sends a result packet to the game client
        /// </summary>
        public static void SendResult(TCPConnection client, ushort msg, ushort result, uint value)
        {
            using (var pak = new PacketOut((ushort)ClientOutPackets.MsgResult))
            {
                pak.WriteShort(msg);
                pak.WriteShort(result);
                pak.WriteUInt32(value);
                pak.FinalizeLengthAndChecksum();
                client.SendTCP(pak);
            }
        }

        public static void SendSPMsg(Player pPlayer, Summon pSummon)
        {
//             TS_SC_SP msg; // [sp+0h] [bp-10h]@1
// 
//             TS_SC_SP::TS_SC_SP(&msg);
//             msg.sp = LOWORD(pSummon->m_nSP);
//             msg.max_sp = LOWORD(pSummon->m_nMaxSP);
//             msg.handle = (pSummon->baseclass_0.baseclass_0.baseclass_0.baseclass_0.vfptr->GetHandle)();
//             PendMessage(&pPlayer->baseclass_0.baseclass_0.baseclass_0, &msg.baseclass_0);
        }

        public static void SendShowCreateAlliance(Player pPlayer)
        {
//             int v1; // ebp@0
//             ArObject *v2; // esi@1
//             ArcadiaServer *v3; // eax@2
//             ArcadiaLock *v4; // eax@2
// 
//             v2 = *(v1 + 8);
//             if ( v2 )
//             {
//                 v3 = ArcadiaServer::Instance();
//                 v4 = ArcadiaServer::_LockObjectWithVisibleRange(
//                          v3,
//                          (v1 + 8),
//                          v2,
//                          "D:\\alienbrainWork\\Source Code\\@Rappelz\\Server\\GameServer_For_Update\\090721_GameServer\\Game\\Message\\SendMessage.cpp",
//                          1744);
//                 ArcadiaAutoLock::ArcadiaAutoLock(
//                     (v1 - 40),
//                     v4,
//                     "D:\\alienbrainWork\\Source Code\\@Rappelz\\Server\\GameServer_For_Update\\090721_GameServer\\Game\\Message\\SendMessage.cpp",
//                     1744);
//                 *(v1 - 4) = 0;
//                 TS_SC_SHOW_CREATE_ALLIANCE::TS_SC_SHOW_CREATE_ALLIANCE((v1 - 20));
//                 StructPlayer::SetLastContact(v2, "alliance", 1);
//                 PendMessage(v2, (v1 - 20));
//                 *(v1 - 4) = -1;
//                 ArcadiaAutoLock::_ArcadiaAutoLock((v1 - 40));
//             }
        }

        public static void SendShowCreateGuild(Player pPlayer)
        {
            if (pPlayer != null)
            {

                RLock rl = RappelzServer.Instance._LockObjectWithVisibleRange(pPlayer);
                AutoLock al = new AutoLock(rl.handle);
                PacketOut pak = new PacketOut(ClientOutPackets.ShowCreateGuild);
                pPlayer.SetLastContact("guild", 1);
                pPlayer.Connection.SendTCP(pak);
//                ArcadiaAutoLock::_ArcadiaAutoLock((v1 - 40));
            }
        }

        public static void SendShowCreatureNameChangeBox(Player pPlayer, uint hSummon)
        {
//             int v2; // ebp@0
//             ArObject *v3; // esi@1
//             ArcadiaServer *v4; // eax@2
//             ArcadiaLock *v5; // eax@2
// 
//             v3 = *(v2 + 8);
//             if ( v3 )
//             {
//                 v4 = ArcadiaServer::Instance();
//                 v5 = ArcadiaServer::_LockObjectWithVisibleRange(
//                          v4,
//                          (v2 + 8),
//                          v3,
//                          "D:\\alienbrainWork\\Source Code\\@Rappelz\\Server\\GameServer_For_Update\\090721_GameServer\\Game\\Message\\SendMessage.cpp",
//                          3237);
//                 ArcadiaAutoLock::ArcadiaAutoLock(
//                     (v2 - 44),
//                     v5,
//                     "D:\\alienbrainWork\\Source Code\\@Rappelz\\Server\\GameServer_For_Update\\090721_GameServer\\Game\\Message\\SendMessage.cpp",
//                     3237);
//                 *(v2 - 4) = 0;
//                 StructPlayer::SetLastContact(v3, "creature_name_change", 1);
//                 TS_SC_SHOW_SUMMON_NAME_CHANGE::TS_SC_SHOW_SUMMON_NAME_CHANGE((v2 - 24));
//                 *(v2 - 17) = *(v2 + 12);
//                 PendMessage(v3, (v2 - 24));
//                 *(v2 - 4) = -1;
//                 ArcadiaAutoLock::_ArcadiaAutoLock((v2 - 44));
//             }
        }

        public static void SendShowSoulStoneCraftWindow(Player pPlayer)
        {
            if (pPlayer == null || pPlayer.Connection == null)
                return;

            PacketOut pak = new PacketOut(ClientOutPackets.ShowSoulstoneCraftWindow);
            pPlayer.SetLastContact("SoulStoneCraft", 1);
            pPlayer.Connection.SendTCP(pak);
        }

        public static void SendShowSoulStoneRepairWindow(Player pPlayer)
        {
            if (pPlayer == null || pPlayer.Connection == null)
                return;

            PacketOut pak = new PacketOut(ClientOutPackets.ShowSoulstoneRepairWindow);
            pPlayer.SetLastContact("RepairSoulStone", 1);
            pPlayer.Connection.SendTCP(pak);
        }

        public static void SendSkillCardInfo(Item item)
        {
/*
            PacketOut packet = new PacketOut((ushort)ClientOutPackets.SkillCardInfo);
            packet.WriteUInt32(item.m_hHandle);
            packet.WriteUInt32(item.m_hBindedTarget);
            player.Connection.SendTCP(packet);

            ArObject *v1; // edi@1
            TS_SC_SKILLCARD_INFO msg; // [sp+8h] [bp-10h]@2

Data           :   this+0x7, Member, Type: unsigned int, item_handle
Data           :   this+0xB, Member, Type: unsigned int, target_handle

            v1 = GameObject.raw_get(pItem->m_Instance.OwnerHandle);
            if ( v1 )
            {
                TS_SC_SKILLCARD_INFO::TS_SC_SKILLCARD_INFO(&msg);
                msg.item_handle = pItem->baseclass_0.baseclass_0.baseclass_0.vfptr->GetHandle((ArSchedulerObject *)pItem);
                msg.target_handle = pItem->m_hBindedTarget;
                PendMessage(v1, &msg.baseclass_0);
            }
*/
        }

        public static void SendSkillMessage(Player player, Creature creature, int skill_id)
        {
            if (player == null || player.Connection == null)
                return;

            PacketOut pak = new PacketOut((ushort)ClientOutPackets.SkillList);

            SkillListPacket sl = new SkillListPacket();
            sl.target = creature.m_hHandle;
            sl.reset = false;

            if ( skill_id >= 0 )
            {
                if (creature.GetSkill(skill_id).m_nSkillUID > 0)
                {
                    SkillListPacket.SkillInfo si = new SkillListPacket.SkillInfo();
                    si.skill_id = skill_id;
                    si.base_skill_level = (byte)creature.GetBaseSkillLevel(skill_id);
                    si.current_skill_level = (byte)creature.GetCurrentSkillLevel(skill_id);
                    si.total_cool_time = creature.GetTotalCoolTime(skill_id);
                    si.remain_cool_time = creature.GetRemainCoolTime(skill_id);
                    sl.skills.Add(si);
                }
            }
            else
            {
                SendSkillMessageSkillFunctor fn = new SendSkillMessageSkillFunctor(player, sl.skills);
                creature.EnumSkill(fn);
            }
            sl.WriteToPacket(pak);
            player.Connection.SendTCP(pak);
        }

        public static void SendSkillResetMessage(Player pPlayer, Creature pCreature)
        {
/*
            ArSchedulerObjectVtbl *v2; // eax@1
            TS_SC_SKILL_LIST msg; // [sp+0h] [bp-10h]@1

            TS_SC_SKILL_LIST::TS_SC_SKILL_LIST(&msg);
            v2 = pCreature->baseclass_0.baseclass_0.baseclass_0.vfptr;
            msg.count = 0;
            msg.reset = 1;
            msg.target = (v2->GetHandle)();
            PendMessage(&pPlayer->baseclass_0.baseclass_0.baseclass_0, &msg.baseclass_0);
*/
        }

        public static void SendStatInfo(Player player, Creature creature)
        {
            PacketOut o = new PacketOut(1000);
            o.WriteUInt32(creature.m_hHandle);
            creature.m_Stat.WriteToPacket(o);
            creature.m_Attribute.WriteToPacket(o);
            o.WriteByte(0);

            player.Connection.SendTCP(o);

            o = new PacketOut(1000);
            o.WriteUInt32(creature.m_hHandle);
            creature.m_StatByState.WriteToPacket(o);
            creature.m_AttributeByState.WriteToPacket(o);
            o.WriteByte(1);
            player.Connection.SendTCP(o);
        }

        public static void SendStateMessage(Player pPlayer, uint target_handle, State pState, bool bIsCancel)
        {
            if (pPlayer == null || pPlayer.Connection == null)
                return;

            PacketOut pak = new PacketOut(ClientOutPackets.State);
            pak.WriteUInt32(target_handle);
            pak.WriteUInt16(pState.m_nUID);
            pak.WriteInt32((int)pState.m_nCode);

            if (bIsCancel)
            {
                pak.WriteUInt16(0);
                pak.WriteUInt32(0);
                pak.WriteUInt32(0);
            }
            else
            {
                pak.WriteUInt16(pState.GetLevel());
                uint t = pState.m_nStartTime[1];
                if (pState.m_nStartTime[0] > t)
                    t = pState.m_nStartTime[0];
                pak.WriteUInt32(t);

                if (!pState.m_bAura)
                {
                    t = pState.m_nEndTime[0];
                    if (t <= pState.m_nEndTime[1])
                        t = pState.m_nEndTime[1];
                    pak.WriteUInt32(t);
                }
                else
                {
                    pak.WriteInt32(-1);
                }
            }
            pak.WriteInt32(pState.m_nStateValue);
            pak.FillString(pState.m_szStateValue, 32);

            pPlayer.Connection.SendTCP(pak);
        }

        public static void SendStatusMessageToFriendOfPlayer(Player player, bool bIsLogin)
        {
            /*
                    int v2; // ebp@0
                    StructPlayer *v3; // esi@1
                    ArSchedulerObjectVtbl *v4; // eax@1
                    const char *v5; // eax@1
                    const char *strResult_20; // [sp+20h] [bp-18h]@2

                    v3 = *(StructPlayer **)(v2 + 8);
                    std::basic_string<char_std::char_traits<char>_std::allocator<char>>::basic_string<char_std::char_traits<char>_std::allocator<char>>(
                    (std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)(v2 - 44),
                    "FSTATUS|");
                    v4 = v3->baseclass_0.baseclass_0.baseclass_0.baseclass_0.vfptr;
                    *(_DWORD *)(v2 - 4) = 0;
                    v5 = (const char *)v4[3].GetHandle((ArSchedulerObject *)v3);
                    std::basic_string<char_std::char_traits<char>_std::allocator<char>>::append(
                    (std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)(v2 - 44),
                    v5);
                    if ( *(_BYTE *)(v2 + 12) )
                    strResult_20 = "|1|";
                    else
                    strResult_20 = "|0|";
                    std::basic_string<char_std::char_traits<char>_std::allocator<char>>::append(
                    (std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)(v2 - 44),
                    strResult_20);
                    *(_DWORD *)(v2 - 48) = v2 - 44;
                    *(_DWORD *)(v2 - 56) = &::::FriendLoginNoticeFunctor::_vftable_;
                    *(_DWORD *)(v2 - 52) = v3;
                    StructPlayer::DoEachFriendOf(v3, (StructPlayer::FriendDenialFunctor *)(v2 - 56));
                    std::basic_string<char_std::char_traits<char>_std::allocator<char>>::_Tidy(
                    (std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)(v2 - 44),
                    1,
                    0);
            */
        }

        public static void SendStatusMessageToFriendOfPlayer(Player player, Player target, bool bIsLogin)
        {
            /*
                        int v3; // ebp@0
                        int v4; // esi@1
                        StructPlayer *v5; // edi@1
                        int v6; // eax@1
                        const char *v7; // eax@1
                        const char *v8; // eax@4
                        const char *strResult_20; // [sp+14h] [bp-18h]@2

                        v4 = *(_DWORD *)(v3 + 8);
                        v5 = *(StructPlayer **)(v3 + 12);
                        std::basic_string<char_std::char_traits<char>_std::allocator<char>>::basic_string<char_std::char_traits<char>_std::allocator<char>>(
                        (std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)(v3 - 44),
                        "FSTATUS|");
                        v6 = *(_DWORD *)v4;
                        *(_DWORD *)(v3 - 4) = 0;
                        v7 = (const char *)(*(int (__thiscall **)(int))(v6 + 60))(v4);
                        std::basic_string<char_std::char_traits<char>_std::allocator<char>>::append(
                        (std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)(v3 - 44),
                        v7);
                        if ( *(_BYTE *)(v3 + 16) )
                        strResult_20 = "|1|";
                        else
                        strResult_20 = "|0|";
                        std::basic_string<char_std::char_traits<char>_std::allocator<char>>::append(
                        (std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)(v3 - 44),
                        strResult_20);
                        v8 = *(const char **)(v3 - 40);
                        if ( *(_DWORD *)(v3 - 20) < 0x10u )
                        v8 = (const char *)(v3 - 40);
                        SendChatMessage(0, 140, "@FRIEND", v5, v8, 0);
                        std::basic_string<char_std::char_traits<char>_std::allocator<char>>::_Tidy(
                        (std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)(v3 - 44),
                        1,
                        0);
            */
        }

        public static void SendTimeSync(Player player)
        {
            PacketOut po = new PacketOut((ushort)ClientOutPackets.TimeSync);
            po.WriteUInt32(Globals.GetArTime());
            player.Connection.SendTCP(po);
        }

        public static void SendTotalItemWearInfoMessage(Player player, Creature target)
        {
            if (player != null && target != null)
            {
                for (int i = 0; i < ItemBase.MAX_ITEM_WEAR; ++i)
                {
                    Item item = target.GetWornItem((ItemBase.ItemWearType)i);
                    if (item != null)
                        SendItemWearInfoMessage(player, target, item);
                }
            }
        }

        public static void SendTradeCancelMessage(Player pClient)
        {
//             TS_TRADE msg; // [sp+0h] [bp-5Ch]@1
// 
//             TS_TRADE::TS_TRADE(&msg);
//             msg.target_player = pClient->m_hTradeTarget;
//             msg.mode = 3;
//             PendMessage(&pClient->baseclass_0.baseclass_0.baseclass_0, &msg.baseclass_0);
        }

        public static void SendUrlList(Player player)
        {
            if (player == null || player.Connection == null)
                return;

            if (!String.IsNullOrEmpty(GameRule.szUrlList) && GameRule.szUrlList.Length < 1000)
            {
                PacketOut po = new PacketOut((ushort)ClientOutPackets.UrlList);
                po.WriteShort((ushort)(GameRule.szUrlList.Length-1));
                po.WriteStringBytes(GameRule.szUrlList);
                player.Connection.SendTCP(po);
            }
        }

        public static void SendWarpMessage(Player pPlayer)
        {
            if (pPlayer == null || pPlayer.Connection == null)
                return;

            PacketOut po = new PacketOut((ushort)ClientOutPackets.Warp);
            po.WriteFloat(pPlayer.mv.x);
            po.WriteFloat(pPlayer.mv.y);
            po.WriteFloat(pPlayer.mv.z);
            po.WriteByte(pPlayer.m_layer);
            pPlayer.Connection.SendTCP(po);
        }

        public static void SendWearMessage(Player player)
        {
            SendWearMessage(player, player);
        }

        public static void SendWearMessage(Player player, Creature creature)
        {
            PacketOut packet = new PacketOut((ushort)ClientOutPackets.WearMessage);
            GetWearMsg(creature, packet);
            player.Connection.SendTCP(packet);

/*
            TS_WEAR_INFO msg; // [sp+8h] [bp-148h]@1
            unsigned int v3; // [sp+14Ch] [bp-4h]@1
            int v4; // [sp+150h] [bp+0h]@1
 * 
* 

            v3 = (unsigned int)&v4 ^ __security_cookie;
            TS_WEAR_INFO::TS_WEAR_INFO(&msg);
            GetWearMsg(pCreature, &msg);
            PendMessage(&pPlayer->baseclass_0.baseclass_0.baseclass_0, &msg.baseclass_0);
*/
        }

        public static void SendWindowMessage(Player pPlayer, string szWindow, string szArgument, string szTrigger)
        {
//             unsigned __int16 v4; // ax@1
//             unsigned __int16 v5; // ax@1
//             unsigned __int16 v6; // ax@1
//             char *v7; // esi@2
//             TS_SC_SHOW_WINDOW msg; // [sp+10h] [bp-7Ch]@1
//             char szTmp[1024]; // [sp+20h] [bp-6Ch]@1
//             unsigned int v10; // [sp+420h] [bp+394h]@1
// 
//             v10 = &szTmp[108] ^ __security_cookie;
//             TS_SC_SHOW_WINDOW::TS_SC_SHOW_WINDOW(&msg);
//             strlen(szWindow);
//             msg.window_length = v4;
//             strlen(szArgument);
//             msg.argument_length = v5;
//             strlen(szTrigger);
//             msg.trigger_length = v6;
//             msg.baseclass_0.size += msg.window_length + msg.argument_length + v6;
//             if ( msg.baseclass_0.size <= 0x400 )
//             {
//                 memcpy(szTmp, &msg, 0xDu);
//                 memcpy(&szTmp[13], szWindow, msg.window_length);
//                 v7 = &szTmp[msg.window_length + 13];
//                 memcpy(&szTmp[msg.window_length + 13], szArgument, msg.argument_length);
//                 memcpy(&v7[msg.argument_length], szTrigger, msg.trigger_length);
//                 PendStream(&pPlayer->baseclass_0.baseclass_0.baseclass_0, szTmp, msg.baseclass_0.size);
//             }
        }

        public static void SendYellChatMessage(int nChatType, uint handle, string szString, uint len)
        {
//             GameObject *v4; // esi@1
//             FileLogHandler *v5; // eax@2
//             XConsole *v6; // eax@2
//             ArObject *v7; // ST04_4@3
//             ArcadiaServer *v8; // eax@3
//             ArcadiaLock *v9; // eax@3
//             FileLogHandler *v10; // eax@4
//             XConsole *v11; // eax@4
//             double v12; // st7@5
//             char v13; // al@5
//             double v14; // st7@5
//             char v15; // ST14_1@5
//             GameObject *v16; // ST0C_4@5
//             ArcadiaServer *v17; // eax@5
//             ArcadiaAutoLock _lock; // [sp+0h] [bp-4Ch]@3
//             ArcadiaLock result; // [sp+14h] [bp-38h]@3
//             char layer[4]; // [sp+18h] [bp-34h]@5
//             StructPlayer::iterator pit; // [sp+1Ch] [bp-30h]@5
//             TS_SC_CHAT_LOCAL msg; // [sp+24h] [bp-28h]@3
//             StructCreature::iterator cit; // [sp+34h] [bp-18h]@1
//             char *src; // [sp+3Ch] [bp-10h]@1
//             int v25; // [sp+48h] [bp-4h]@1
//             char pBuffer[16384]; // [sp+4Ch] [bp+0h]@1
//             unsigned int v27; // [sp+404Ch] [bp+4000h]@1
// 
//             v27 = pBuffer ^ __security_cookie;
//             src = szString;
//             StructCreature::get(&cit, handle);
//             v4 = cit.baseclass_0.m_pObject;
//             v25 = 0;
//             if ( cit.baseclass_0.m_pObject )
//             {
//                 v7 = cit.baseclass_0.m_pObject;
//                 v8 = ArcadiaServer::Instance();
//                 v9 = ArcadiaServer::_LockObjectWithSpecificRange(
//                          v8,
//                          &result,
//                          v7,
//                          0x28u,
//                          "D:\\alienbrainWork\\Source Code\\@Rappelz\\Server\\GameServer_For_Update\\090721_GameServer\\Game\\Message\\SendMessage.cpp",
//                          827);
//                 ArcadiaAutoLock::ArcadiaAutoLock(
//                     &_lock,
//                     v9,
//                     "D:\\alienbrainWork\\Source Code\\@Rappelz\\Server\\GameServer_For_Update\\090721_GameServer\\Game\\Message\\SendMessage.cpp",
//                     827);
//                 LOBYTE(v25) = 1;
//                 TS_SC_CHAT_LOCAL::TS_SC_CHAT_LOCAL(&msg);
//                 msg.type = nChatType;
//                 msg.len = len + 1;
//                 msg.baseclass_0.size += (len + 1);
//                 msg.handle = handle;
//                 if ( msg.baseclass_0.size <= 0x4000 )
//                 {
//                     memcpy(pBuffer, &msg, 0xDu);
//                     memcpy(&pBuffer[13], src, msg.len);
//                     v12 = g_nRegionSize;
//                     *(&v25 + msg.baseclass_0.size + 3) = 0;
//                     v13 = v4->baseclass_0.layer;
//                     *&src = v12;
//                     layer[0] = v13;
//                     v14 = v4->baseclass_0.mv.baseclass_0.x / *&src;
//                     pit.baseclass_0.m_pObject = (v4->baseclass_0.mv.baseclass_0.y / *&src);
//                     v15 = v13;
//                     v16 = pit.baseclass_0.m_pObject;
//                     v17 = ArcadiaServer::Instance();
//                     ArcadiaServer::BroadcastToSpecificRegion(v17, v14, v16, 0x28u, v15, pBuffer);
//                     StructPlayer::get(&pit, handle);
//                     LOBYTE(v25) = 2;
//                     if ( pit.baseclass_0.m_pObject )
//                         SendResult(&pit.baseclass_0.m_pObject->baseclass_0, 0x14u, 0, 0);
//                     pit.baseclass_0.vfptr = &StructPlayer::iterator::_vftable_;
//                     GameObject::iterator::_iterator(&pit.baseclass_0);
//                 }
//                 else
//                 {
//                     v10 = FileLogHandler::GetFileLogHandler();
//                     (v10->vfptr->LogString)(v10, "SendYellChatMessage +¦++-", msg.baseclass_0.size);
//                     v11 = XConsole::Inst(0);
//                     XConsole::Printf(v11, "SendYellChatMessage +¦++-");
//                 }
//                 LOBYTE(v25) = 0;
//                 ArcadiaAutoLock::_ArcadiaAutoLock(&_lock);
//             }
//             else
//             {
//                 v5 = FileLogHandler::GetFileLogHandler();
//                 (v5->vfptr->LogString)(v5, "-++t¦--", handle);
//                 v6 = XConsole::Inst(0);
//                 XConsole::Printf(v6, "-++t¦--");
//             }
//             cit.baseclass_0.vfptr = &StructCreature::iterator::_vftable_;
//             GameObject::iterator::_iterator(&cit.baseclass_0);
        }














    }
}
